次のクラス定義を考えてみましょう:型推論入力paramenters
class Person[+T <: Person[T]]
class Student() extends Person[Student]
class Professor() extends Person[Professor]
私は学生と教授とのリストをしたいと思います:
val persons = List(new Student(), new Professor())
しかし、これは、次のエラーでコンパイルに失敗します。
type arguments [Person[Person[Any]]] do not conform to class Person's type parameter bounds [+T <: Person[T]]
Daniel C. Sのおかげで私の関連する以前の質問へのobralの答えHow to define case classes with members with unbound type parameters?私は実在のタイプがここでトリックをするだろうと知っています。これは、コンパイルされます。
val persons = List[Person[T] forSome {type T <: Person[T]}](new Student(), new Professor())
問題は、クラスPersonの宣言の型パラメータに上限<: Person[T]
によって引き起こされます。上限を削除すると、コンパイラはコンパイルするリストの型パラメータを推測できるようになります。List[Person[Person[Person[Any]]]]
までは私が見ることができます。
質問
- なぜコンパイラがコンパイルになるだろう、リストのための任意の型を推論することはできませんか?
- 存在タイプは最も冗長であり、さらに難しいかもしれません(上記の前の質問に対するDanielの回答を参照してください):生徒と教授のリストを作成するための明示的な存在タイプの代わりがありますか?
あなたは 'Person'ため、このような複雑でジェネリック型を必要としないのはなぜ?あなたの例でコンパイラが推測するものは何でしょうか? – paradigmatic
@ paradigmaticこれは、タイプPersonが拡張型であることを知るためのものです。このように 'Person'の' def동료:Seq [T] 'メソッドを定義して、' Student'のインスタンスを返すメソッドと 'Professor'のインスタンスのための教授を返すことができます。そして、私が作成したListオブジェクトの型引数を推論するために、コンパイラに伝えたいと思います。 –
@paradigmatic申し訳ありませんが、私は初めてそれを逃しました:私は本当にどのようなタイプ、エラーを生成しないだけ気にしません。これは、実在の型でも、 'Person [_]'でもかまいません。意味的には私は人のリストが好きです... –