2016-07-27 53 views
0

下面的代码工作正常如果使用链方法时在继承类

abstract class Base { 
    def append(value: Any): this.type = this 
} 

class Axis extends Base { 
    def text(value: String): this.type = append(value) 
} 

class XAxis extends Axis { 
    def position(value: Int): this.type = append(value) 
} 

def main(args: Array[String]): Unit = { 
    new XAxis().text("hello").position(0) 
} 

不指定this.type而如果我在Axis.text

class Axis extends Base { 
    // here we don't explicitly specify return type this.type 
    def text(value: String) = append(value) 
} 
删除this.type为什么斯卡拉报告错误

斯卡拉报告

position不是Axis的成员。

的方法调用链

new XAxis().text将调用append

追加有返回类型this.type

thisXAxis一个实例。

所以this.typeAxis

因此无论指定this.type为返回类型,斯卡拉应该总是可以推断到真正的实例类型。

为什么它在我们明确指定返回类型this.type时有效?

但是,当我们没有明确指定返回类型this.type时,它不起作用?

回答

2

当您不指定方法的返回类型时,编译器会推断它。更具体地说,编译器总是会推断出最精确的类型,但从来没有单一类型(可以通过value.type表示法识别)。因此,在这种情况下,将推断方法text以返回类型Axis,这是类别Axis中最精确的超类型this.type

+0

你的意思是说,当调用'text'时,编译器知道它至少是Axis,但编译器不会试图推断出真正的类型? –

+0

是的。但请注意,'this.type'永远不会与“Axis”或“XAxis”“平等”。 'this.type'是一个单例类型,这意味着该类型的唯一实例是当前对象。在你的第一个例子中'this.type'将是'XAxis'的一个子类型,所以编译器知道它有一个叫'position'的方法。 –

+0

Scala编译器需要一些信息来推断类型。对于'text'方法,唯一的信息是调用'append',它的返回类型是'this.type'。我们如何解释'永远不会推断到单身类型'?因为singleton类型是'text'可以得到的。 –