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)をタイプに制限したため、エラーが発生していますSelf。あなたが言うとき、そのオブジェクトはあなたが尋ねたようなnew Self with SelfAwareタイプなので、これはOKです。Selfしかし、あなたが言うとき、何らかの形でのサブタイプであるnew X with SelfAware証拠はありません。XSelf

タイプの新しいオブジェクトではX with SelfAware、そのselfメンバーのタイプは何でしょうか?まあ、それはタイプSelfではなく、タイプXです。ただし、タイプがである必要があるSelfAwareようにトレイトを定義したため、タイプエラーが発生します。selfSelf

于 2012-04-24T03:03:31.000 に答える
21

私もここで答えを見つけました:http://markthomas.info/blog/?p = 92

自己タイプ

Orderedは、どのクラスにも混在させることができます。混合されるクラスのメソッドやフィールドには依存しません。トレイトが混合されているクラスのフィールドまたはメソッドを使用できると便利な場合があります。これは、トレイトの自己タイプを指定することで実行できます。自己タイプは、次のようにクラスまたはトレイトに指定できます。

trait SpellChecker { self =>
  ...
}

この特性のコンテキスト内の自己はこれを参照します。これをエイリアシングすると、特定のこれにアクセスするのが難しいネストされたクラスまたは特性に役立ちます。構文を拡張して、これの下限を指定できます。これが行われると、トレイトまたはクラスはこの下限クラスの機能を使用できるため、動作を拡張または変更できます。

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 に答える