关于这个类型,令人惊讶的等价和非等价



无论是从Trait内部还是从创建对象的范围引用this.type,都会产生不同的结果,令人惊讶。

import scala.reflect.runtime.universe._
trait Trait {
  val ttag = typeOf[this.type]
  println(s"Trait constructor: $this")
}
object Instance1 extends Trait
object Instance2 extends Trait
println(typeOf[Instance1.type] =:= typeOf[Instance2.type])  // Should be false
println(Instance1.ttag =:= Instance2.ttag)                  // Should be false
println(Instance1.ttag =:= typeOf[Instance1.type])          // Should be true

这是输出:

false    // As expected: the singleton types of two objects are different.
Trait constructor: $line9.$read$$iw$$iw$$iw$$iw$Instance1$@58c46295
Trait constructor: $line10.$read$$iw$$iw$$iw$$iw$Instance2$@452451ba
true     // But the this.type tags are equivalent
false    // and the this.type tag is not equivalent to the singleton type.

因此,有两个不同的对象,但显然每个对象都为其this.type获得了一个等效的类型标记,从封闭的范围来看,这与对象的.type不等效。

这是编译器错误吗?如果不是,你能解释一下为什么这种行为有意义吗?

(我运行的是Scala2.11.2。我用self别名this进行了尝试,得到了相同的结果。(

下面的程序先打印false,然后打印true。在我看来,这两种情况之间不应该有实质性的区别(尽管这实际上更多的是一种观点;我真的不能说是否有原因(:

import scala.reflect.runtime.universe._
object Test2 extends App {
  def foo(): Type = {
    object a
    typeOf[a.type]
  }
  println(foo() =:= foo()) // false
  trait Trait {
    val ttag = typeOf[this.type]
  }
  object Instance1 extends Trait
  object Instance2 extends Trait
  println(Instance1.ttag =:= Instance2.ttag) // true
}

相关内容

  • 没有找到相关文章

最新更新