首页 > 关于scala中this.type的一个问题

关于scala中this.type的一个问题

定义两个类:

class A { def method1 = this } 
class B extends A { def method2 = this }
val b = new B

然后我查看b.method1的类型:

scala> b.method1.getClass
res29: Class[_ <: A] = class B

这种情况下无法调用b.method1.method2

scala> b.method1.method2
<console>:11: error: value method2 is not a member of A
              b.method1.method2

将A和B两个类的定义加上this.type:

class A { def method1: this.type = this } 
class B extends A { def method2: this.type = this } 
val b = new B

再查看b.method1的类型:

scala> b.method1.getClass
res31: Class[_ <: B] = class B

这时可以调用b.method1.method2方法:

scala> b.method1.method2
res32: b.type = B@4ff3ac

我的问题是:
res29: Class[_ <: A] = class Bres31: Class[_ <: B] = class B 这样的类型格式是什么意思?看上去觉得这两个都是B的类,为什么前一个不能调用B的方法呢?


res29: Class[_ <: A] = class B
的意思是结果参数 res29 的类型是 Class[_ <: A],值为 class B。 _ <: A 表示任意 A 的子类型。

对于 b.method1.method2 不能调用的原因可以参看一下:http://scalada.blogspot.com/2008/02/thistype-for-chaining-method-calls.html
我估计你的问题也是从这篇帖子来吧。还可以看看这篇问题:
http://stackoverflow.com/questions/4313139/how-to-use-scalas-this-typing-abstract-types-etc-to-implement-a-self-type

主要原因就是:
class A { def method1 = this }
中 method1 返回类型为 A,没有写出来但编译器会推断为 A。确认方法是自己在这里填上 : A 看编译器报错不。
所以 b.method1 返回的是 A 类型的对象,A 类型中没有 method2。

而带上 this.type 后:
class A { def method1: this.type = this }
this.type 是 method1 的返回值,这个返回值很特殊,得在运行期才会真正计算出具体类型,所以当对象实际类型是 B 的时候,调用 b.method1 返回的还是子类 B 类型,而不是 A 类型。这个就是 this type 的用途,是 scala 为了满足这类需求专门设计的关键字。

【热门文章】
【热门文章】