1

對象的集合類型推斷考慮下面的類定義:用於實現類與(個體經營)型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]]]]就我所見。

問題

  1. 爲什麼不能編譯器推斷出任何類型的列表,它將使編譯?
  2. 存在性類型是最不詳細的,並且可能會更棘手(請參閱Daniel對我之前提到的問題的回答):是否有替代顯式存在類型來創建學生和教授的列表?
+0

爲什麼你需要一個泛型類型,例如用於'Person'複雜性?你希望編譯器在你的例子中推斷出什麼? – paradigmatic 2012-04-25 21:05:36

+0

@paradigmatic這是爲類型人知道哪些是擴展類型。像這樣,你可以定義一個方法'def colleagues:'Person'中的Seq [T]'返回Student'的實例和Professor'的實例的教授。我想編譯器推斷我創建的List對象的類型參數。 – 2012-04-25 21:12:37

+0

@paradigmatic對不起,我第一次錯過了:我真的不在乎什麼類型,只是一個不會產生錯誤。這可以是一個存在的類型,或者'Person [_]'。在語義上我想要一個人的名單...... – 2012-04-25 21:40:11

回答

1

我相信你已經在你的第二個評論

val persons = List[Person[_]](new Student(), new 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) 

馬丁·奧德斯基也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)