scala 如何使用带有`self`引用的scala特性?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10291176/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 04:06:48  来源:igfitidea点击:

How to use scala trait with `self` reference?

scala

提问by Evans Y.

I saw some code write trait as following:

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

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

I'd like to know why the error happened and how to use trait in this way?

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

采纳答案by Apocalisp

The error is occurring because you have constrained the type of the thisreference (which you have named self) to be of type Self. When you say new Self with SelfAware, this is OK, because that object is of type Selflike you asked. But when you say new X with SelfAware, there is no evidence that Xis in any way a subtype of Self.

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

In your new object of type X with SelfAware, what would be the type of its selfmember? Well, it would not be of type Self, but of type X. But you have defined the trait SelfAwareso that selfmust be of type Self, so you get a type error.

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

回答by Evans Y.

I also found the answer here: http://markthomas.info/blog/?p=92

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

Self Types

自我类型

Ordered can be mixed in to any class; it doesn't depend on any methods or fields of the class that it is mixed in to. Sometimes it's useful for a trait to be able to use the fields or methods of a class it is mixed in to, this can be done by specifying a self type for the trait. A self type can be specified for a class or a trait as follows:

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

trait SpellChecker { self =>
  ...
}

self within the context of this trait will refer to this. Aliasing this is useful for nested classes or traits where it would otherwise be difficult to access a particular this. The syntax can be extended to specify a lower-bounds on this, when this is done the trait or class can use the features of this lower-bound class, so it can extend or modify its behaviour.

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

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

The compiler will check that any class in a hierarchy including SpellChecker is or extends RandomAccessSeq[char], so SpellChecker can now use the fields or methods of RandomAccessSeq[char]

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

回答by Dan Burton

To answer the other half of your question (why does println(s.self)produce an error?), that is because selfis not a field of SelfAware. It can be used to define such fields, however:

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

trait SelfAware { self =>
  val me = self
}

class X
val x = new X with SelfAware
println(s.me)