2017-07-20 93 views
0

已經有關於我想要做什麼的信息,但還沒弄明白。我想實例化這樣的綁定爲一個環境傳送一個類型的元素,東西:Scala 2.12,實例化類型參數?

case class Person(name: String) 
case class Dog(name: String) 

abstract case class Message[T](result: Map[String, T]) 

// using Person as a type here 
case class PersonMessage(val result: Map[String, Person]) extends Message[Person](result) 

// using Dog as a type here 
case class DogMessage(val result: Map[String, Dog]) extends Message[Dog](result) 

我當然可以舉例說明這些對象:

val pm: PersonMessage = PersonMessage(Map("joe" -> Person("joe"))) 
val dm: DogMessage = DogMessage(Map("blacky" -> Dog("blacky"))) 

,但我能做到這一點在泛型函數?

// should return a PersonMessage or a DogMessage 
def myfunction[T, U <: Message[T]](customName: String): U = { 
    U(Map(customName -> T(customName))) 
} 

val p: PersonMessage = myFunction[Person, PersonMessage]("joe") 
val d: DogMessage = myFunction[Dog, DogMessage]("blacky") 

此語法不起作用,但有沒有其他方法可以實現此目的?感謝您的任何提示。

回答

1

問題是,通過只定義類型TU <: Message[T]您無法保證構造函數採取什麼樣的參數。爲什麼不能用T將其設置爲某種沒有單字符參數構造函數的類型呢?相反,你可以顯式地傳入適當類型的構造函數。以下是我將如何處理它:

def myFunction[T, U <: Message[T]](customName: String, mkT: String => T, mkU: Map[String, T] => U): U = { 
    mkU(Map(customName -> mkT(customName))) 
} 

val p: PersonMessage = myFunction("joe", Person, PersonMessage) 
val d: DogMessage = myFunction("blacky", Dog, DogMessage) 
+0

謝謝喬!我唯一需要做的其他事情就是讓基類成爲類(而不是case類),因爲這些類是不可擴展的。 – ticofab