3

私は scala の型システムをいじっていて、奇妙なケースを見つけました。私には、共変と共分散を理解していないと信じる強い理由があります。

これは私の問題ケースです:

Point と、Point のサブクラスである ColorPoint という 2 つのクラスがあります。

class Point(val x : Int, val y : Int)
class ColorPoint(x : Int, y : Int, val red : Int, val green : Int, val blue : Int) extends Point(x,y) 

このクラスは B を A にキャストしますが、B は A のスーパータイプである必要があります。

class CoVariance[+A]{
 def cast[B >: A](x : B) : A = {
  return x.asInstanceOf[A] 
 }
}

このクラスは B を A にキャストしますが、B は A のスーパータイプである必要があります。

class ContraVariance[-A]{
 def cast[B, A <: B](x : B) : A = {
    return x.asInstanceOf[A]
 }
}

ケース 1:

val co = new CoVariance[Point]
val color_point = new ColorPoint(1,2,3,4,5)
val point_co = co.cast(color_point) 
println(point_co.x)

これを書き出すと:

// Covariance[Point] -> 
// cast[B :> Point](x : B) : Point -> (fill in ColorPoint)
// Cast[ColorPoint :> Point] : Point 

ColorPoint は Point のスーパータイプではないため、これは間違っていると思いますが、scala は文句を言いません。

次の:

val contra = new ContraVariance[Point]
val color_point_contra = new ColorPoint(1,2,3,4,5)
val point_contra = contra.cast(color_point_contra) 
println(point_contra.x)

これを書き出すと:

// ContraVariance[Point] -> 
// cast[B, Point <: B](x : B) : Point -> (fill in ColorPoint)
// cast[ColorPoint, Point <: ColorPoint] : Point 

これも間違っていると思いますが、scala は文句を言いません。Point は ColorPoint のサブタイプではないと思います。

私の推論は正しいですか、それとも何かが欠けていますか?

4

2 に答える 2

2
  1. asInstanceOf[T]タイプチェックを無視します。したがって、次のキャストを使用することもできます。

    def cast[B](a:A):B = a.asInstanceOf[B]
    

    Aおよびの場合B

    したがって、あなたの場合、Scala は文句を言いません。

  2. 私の理解が正しければcast、型が適切な関係 (親子) にある場合にのみメソッドを使用する必要があります。+/-クラス宣言をする必要はないと思います。2 つの異なるキャストのみ:

    implicit class CastToParent[A](a:A) {
      def cast[B >: A]:B = a.asInstanceOf[B]
    }
    
    
    implicit class CastToChild[A](a:A) {
      def cast[B <: A]:B = a.asInstanceOf[B]
    }
    

    これにより、目的の変換が可能になります。

    trait A
    trait B extends A
    trait C
    val a:A = new B {}
    val b   = a.cast[B] //parent to child
    val a1  = b.cast[A] //child to parent.
    val c   = a.cast[C] // don't compile
    
于 2013-10-29T20:38:05.947 に答える