9

したがって、これはこのJavaの質問をscalaにかなり直接移植したものです

次のように、ジェネリック パラメータを使用する多くのトレイトがあります。

 trait Ident { }

 trait Container[I <: Ident] {
   def foo(id: I): String
 }

 trait Entity[C <: Container[I], I <: Ident] {
   def container: C
   def foo(id: I) = container.foo(id)
 }

これは機能しますが、Entity のサブクラスを定義するときに Ident の型と Container の型を指定する必要があるため、少し扱いに​​くいです。実際には、コンテナの型だけで十分な型情報になる場合:

class MyIdent extends Ident { }
class MyContainer extends Container[MyIdent] { } 
class MyEntity extends Entity[MyContainer,MyIdent] { }
//                                        ^^^^^^^ shouldn't really be necessary

存在型を使用すると、Entity が 2 つのパラメーターを受け取る必要がなくなりますが、もちろん後で参照することはできません。

trait Entity[C <: Container[I] forSome { type I <: Ident }] {
  def container: C
  def foo(id: I) = container.foo(id)
//           ^^^ complains it has no idea what 'I' is here
}

同様に、メンバー型を使用するように変換しても機能しません...

trait Ident { }

trait Container {
  type I <: Ident
  def foo(id: I): String
}

trait Entity {
  type C <: Container
  def container: C
  def foo(id: C#I) = container.foo(id)
//                                 ^^ type mismatch
}

Scalaでこの問題に対するエレガントな解決策があるかどうか、誰かが知っていますか?

4

1 に答える 1