gpt4 book ai didi

scala - Scala 中的 F 界多态性

转载 作者:行者123 更新时间:2023-12-02 05:19:47 25 4
gpt4 key购买 nike

我正在使用 Scala 2.10-RC5

这是我的代码:

object Fbound {
abstract class E[A <: E[A]] {
self: A =>
def move(a: A): Int
}
class A extends E[A] {
override def toString = "A"
def move(a: A) = 1
}
class B extends E[B] {
override def toString = "B"
def move(b: B) = 2
}
def main(args: Array[String]): Unit = {
val a = new A
val b = new B
val l = List(a, b)
val t = l.map(item => item.move(null.asInstanceOf[Nothing]))
println(t)
}
}

程序运行时出现异常:

Exception in thread "main" java.lang.NullPointerException
at fb.Fbound$$anonfun$1.apply(Fbound.scala:20)
at fb.Fbound$$anonfun$1.apply(Fbound.scala:20)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
at scala.collection.immutable.List.foreach(List.scala:309)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
at scala.collection.AbstractTraversable.map(Traversable.scala:105)
at fb.Fbound$.main(Fbound.scala:20)
at fb.Fbound.main(Fbound.scala)

我的问题是:

  1. 为什么它通过了编译器但在运行时却失败了?
  2. 在底部添加一行 - val t1 = l.map(item => item.move(item)) 会使编译器失败,为什么?

最佳答案

您的代码 null.asInstanceOf[Nothing]编译因为 Nothing是所有事物的子类,因此符合 move 所需的类型.不用说,它会在运行时抛出异常。

当你尝试编译你给出的第二行时,你会在这个错误的行中得到一些东西:

<console>:19: error: type mismatch;
found : E[_6(in value $anonfun)] where type _6(in value $anonfun) >: B with A
<: E[_ >: B with A <: Object]
required: <root>._6

当您将两个实例放在同一个 List 中时,您丢失了有关其元素类型的重要信息。编译器无法确保 T >: B with A <: E[_ >: B with A] 类型的元素可以传递给 move相同类型的对象的方法,同样的方式,你不能这样做:

val c: E[_ >: B with A] = new A
val d: E[_ >: B with A] = new B
c.move(d) // note: the _ in c and d declarations are different types!

我对 self 类型的了解还不够,无法完全确定这个解释,但在我看来,这是一个类级别的限制,而不是实例级别的限制。换句话说,如果你丢失了关于 E 中类型参数的信息。 ,你不能指望编译器知道 move参数特定类型。

对于实例级别的限制,您有 this.type .如果定义 move作为:

def move(a: this.type): Int

您的代码可以编译,但我认为这不是您想要的,因为 move将只接受您调用它的相同实例,这是无用的。

我想不出有什么方法可以按照您想要的方式强制执行该限制。我建议您尝试使用类型变量(即在类 type T = A 中定义类型变量 E )来做到这一点,据我所知,这些变量在某种程度上绑定(bind)到实例。也许您可以更详细地说明您的具体情况?

关于scala - Scala 中的 F 界多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14067406/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com