考虑以下类定义:
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. Sobral回答我之前提到的相关问题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类声明的type参数中的上限<: Person[T]
引起的。删除上限允许编译器推断列表的类型参数,使其编译:{{1}}就我所见。
问题
答案 0 :(得分:1)
我相信你在第二条评论中提到了一个可能的替代方案
val persons = List[Person[_]](new Student(), new Professor())
但是根据我的理解,Scala中用于执行此类操作的惯用方法是在Person中使用类型声明并在Student和Professor中定义:
trait Person {
type PersonImpl <: Person
def colleagues: Seq[PersonImpl]
}
class Student extends Person {
type PersonImpl = Student
def colleagues = Seq(this)
}
class Professor extends Person {
type PersonImpl = Professor
def colleagues = Seq(this)
}
val persons = List(new Student, new Professor)
Martin Odersky也用scala语言提到he's thinking about unifying type parameters and abstract type members。
根据您的实际用例,最简单的解决方案可能是依赖方法覆盖:
trait Person {
def colleagues: Seq[Person]
}
class Student extends Person {
def colleagues: Seq[Student] = Seq(this)
}
class Professor extends Person {
def colleagues: Seq[Professor] = Seq(this)
}
val persons = List(new Student, new Professor)