0

我在scala中有以下函数定义:

trait GenExtractor[+R] P
      def orElseExtractor[R2<: Super, Super>: R](g: GenExtractor[T, R2]): GenExtractor[T, Super] =
        new OrElse[T, Super](this, g)
}

这应该结合2个GenExtractors:

GenExtractor[A]
GenExtractor[B]

进入:

GenExtractor[C]

其中 C 是 A 和 B 的共同超类型

但是,当我尝试调用此函数时:

val genExtractor = new GenExtractor[R](...parameters...)
val combined = genExtractor.orElseExtractor[Null, R] {
      _: FetchedRow => null
    }

我收到以下错误:

Error:(84, 47) type arguments [Null,R] do not conform to method orElseExtractor's type parameter bounds [R2 <: Super,Super >: R]
    def orNull: Extractor[R] = orElseExtractor[Null, R] {
                                              ^

这显然是一个误报,因为在这种情况下:

type R2 = Null
type Super = R

满足条件:Null <: R & R >: R

为什么scala编译器给了我这个错误?我应该怎么做才能修复它?

4

1 回答 1

3

为什么会Null是泛型的子类型R?不是编译器偏离标准,而是基本假设Null <: R始终正确。这里有一些有趣的例子,它们与原语有关。

Some(5).orNull将产生error: Cannot prove that Null <:< Int

这是你的差距,你可以在 REPL 中尝试一下:

implicitly[Null <:< AnyRef] // will compile
implicitly[Null <:< AnyVal] // blows up, primitives are not included.

在类型系统中,所有类型的超类型,唯一保证满足您期望的任何此类关系的东西是scala.Nothing, not scala.Null

nullJVM上的设计主要是为了处理类型信息的缺失,而不是处理类型系统层次结构。为此,您拥有Nothing,AnyRefAnyVal所有其他有趣的东西。

于 2016-06-05T02:19:31.650 回答