Scala:如何让这个玩具协变示例工作?
Scala: How do I get this toy covariant example to work?
简单协方差示例:为什么 asInstance 有效?
class Fruit(name: String) { def get_name = name}
class Apple(name: String) extends Fruit(name)
class Orange(name: String) extends Fruit(name)
class BigOrange(name:String) extends Orange(name)
// Contrived but simple covariant box with some utility functions
class Box[+T <: Fruit] {
def foo[ U >: T] (item: U): String = item.asInstanceOf[T].get_name
}
val f = new Fruit("fruit")
val a = new Apple("apple")
val o = new Orange("orange")
// Error. Makes sense apples cannot be casted to oranges
println( a.asInstanceOf[Orange])
val bo1 = new Box[Orange]
println(bo1.foo(a)) // Returns Apple ! How was an apple seemingly casted to an orange?
那么为什么最后一行有效?逻辑不是要求传递的苹果被转换为橙子吗?
第二个问题:为什么这段代码给我 get_name 无法识别的错误?
class Box[+T <: Fruit] (item: T) {
val contents = item
def foo[ U >: T] (item: U): String = item.get_name
}
在 [+T <: Fruit] 和 U >: T 之间,不是很明显该项目应该有一个 get_name 吗?为什么会出错?
asInstanceOf[T]
实际上什么都不做,因为 Box
的类型 T
被删除了。您还应该从编译器那里得到警告。
这里的问题...
class Box[+T <: Fruit] (item: T) {
val contents = item
def foo[U >: T] (item: U): String = item.get_name
}
... 是您将一个 item
与另一个重叠。第一个 item: T
、 确实 有编译器可以识别的 get_name
成员,但第二个 item: U
没有。它可能是 Fruit
的父类或超类,这意味着不能保证 get_name
成员。
Between the [+T <: Fruit] and U >: T, is'nt it obvious that item should have a get_name?
当然不是。例如,U = Any
满足约束条件,没有get_name
成员。
简单协方差示例:为什么 asInstance 有效?
class Fruit(name: String) { def get_name = name}
class Apple(name: String) extends Fruit(name)
class Orange(name: String) extends Fruit(name)
class BigOrange(name:String) extends Orange(name)
// Contrived but simple covariant box with some utility functions
class Box[+T <: Fruit] {
def foo[ U >: T] (item: U): String = item.asInstanceOf[T].get_name
}
val f = new Fruit("fruit")
val a = new Apple("apple")
val o = new Orange("orange")
// Error. Makes sense apples cannot be casted to oranges
println( a.asInstanceOf[Orange])
val bo1 = new Box[Orange]
println(bo1.foo(a)) // Returns Apple ! How was an apple seemingly casted to an orange?
那么为什么最后一行有效?逻辑不是要求传递的苹果被转换为橙子吗?
第二个问题:为什么这段代码给我 get_name 无法识别的错误?
class Box[+T <: Fruit] (item: T) {
val contents = item
def foo[ U >: T] (item: U): String = item.get_name
}
在 [+T <: Fruit] 和 U >: T 之间,不是很明显该项目应该有一个 get_name 吗?为什么会出错?
asInstanceOf[T]
实际上什么都不做,因为 Box
的类型 T
被删除了。您还应该从编译器那里得到警告。
这里的问题...
class Box[+T <: Fruit] (item: T) {
val contents = item
def foo[U >: T] (item: U): String = item.get_name
}
... 是您将一个 item
与另一个重叠。第一个 item: T
、 确实 有编译器可以识别的 get_name
成员,但第二个 item: U
没有。它可能是 Fruit
的父类或超类,这意味着不能保证 get_name
成员。
Between the [+T <: Fruit] and U >: T, is'nt it obvious that item should have a get_name?
当然不是。例如,U = Any
满足约束条件,没有get_name
成员。