28

我看到一些代码编写特征如下:

trait SelfAware { self: Self =>
 ....
}

class Self
val s = new Self with SelfAware // this is ok
println(s.self) // error happened

class X
new X with SelfAware // error happened here

我想知道为什么会发生错误以及如何以这种方式使用特征?

4

3 回答 3

22

发生错误是因为您已将this引用的类型(您已命名self)限制为 type Self。当您说 时new Self with SelfAware,这没关系,因为该对象的类型Self与您询问的一样。但是当你说的时候new X with SelfAware,没有任何证据表明它XSelf.

在您的新类型对象中X with SelfAware,其self成员的类型是什么?好吧,它不是 type Self,而是 type X。但是您已经定义了特征SelfAware,因此它self必须是 type Self,所以您会收到类型错误。

于 2012-04-24T03:03:31.000 回答
21

我也在这里找到了答案:http: //markthomas.info/blog/ ?p=92

自我类型

Ordered 可以混入任何类;它不依赖于它所混入的类的任何方法或字段。有时,一个 trait 能够使用它所混入的类的字段或方法很有用,这可以通过为 trait 指定一个自身类型来完成。可以为类或特征指定自我类型,如下所示:

trait SpellChecker { self =>
  ...
}

在 this trait 的上下文中的 self 将引用 this。别名 this 对于嵌套类或特征很有用,否则很难访问特定的 this。可以扩展语法以指定 this 的下限,完成此操作后,特征或类可以使用此下限类的功能,因此它可以扩展或修改其行为。

trait SpellChecker { self: RandomAccessSeq[char] =>
  ...
}

编译器将检查包括 SpellChecker 在内的层次结构中的任何类是否是或扩展了 RandomAccessSeq[char],因此 SpellChecker 现在可以使用 RandomAccessSeq[char] 的字段或方法

于 2012-04-24T03:09:21.973 回答
12

要回答您问题的另一半(为什么会println(s.self)产生错误?),那是因为self不是SelfAware. 但是,它可用于定义此类字段:

trait SelfAware { self =>
  val me = self
}

class X
val x = new X with SelfAware
println(s.me)
于 2012-04-24T04:25:59.507 回答