10

Javaのこのコードは、エラーなしでコンパイルされます。

interface T {
    interface Q {
    }
}

class C implements T.Q {
}

一方、Scalaのこのコードは次のことを行いません。

trait T {
    trait Q {
    }
}

class C extends T.Q {
}

JavaコードリストのScalaへの正しい翻訳(存在する場合)は何ですか?

言語デザインに関する理論的な説明は大歓迎です。

4

2 に答える 2

11

内部タイプは、トレイトQの特定のインスタンス実装に対してのみ定義されます。TScalaにはパスに依存する型があるため、の各インスタンスにTは独自のサブトレイトがありQます。

scala> trait T {
     |   trait Q
     | }
defined trait T

scala> class C extends T {
     |   def getQ: this.Q = new this.Q {}
     | }
defined class C

scala> val inC = (new C).getQ
inC: C#Q = C$$anon$1@3f53073a


scala> val c = new C
c: C = C@1a7e4ff0

scala> new c.Q {}
res4: c.Q = $anon$1@36bbb2f5

C特定のインスタンスに依存せずに、クライアントが実装する一般的な動作のインターフェイスが必要な場合は、Object

scala> object T {
     |   trait Q {
     |     def implementMe: Unit
     |   }
     | }
defined module T

scala> val inT = new T.Q {
     |   def implementMe = println("implemented!")
     | }
inT: T.Q = $anon$1@20f2a08b

scala> inT.implementMe
implemented!

なぜパス依存型なのか?

デザイン上の理由はこちらをご覧ください

于 2013-03-25T13:52:23.950 に答える
3

それをしてはいけない。型がネストされると、パス依存型と呼ばれるものが作成されます。つまり、内部エンティティの各インスタンスの型は、それが構築されている特定のインスタンスに関連付けられます。

つまり、インターフェイスQには、Tのインスタンスとは別に参照できる独立した存在がありません。

于 2013-03-25T13:40:10.617 に答える