2017-07-20 2 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

タイプTまたはU <: Message[T]を定義するだけで、コンストラクタがどのような種類の引数を取るかは保証されません。なぜ誰かがそれをTと呼んで、1つの文字列引数のコンストラクタを持たない型に設定できないのですか?代わりに、適切な型のコンストラクタを明示的に渡すことができます。ここで私はそれをどう扱うのですか:

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

ありがとうジョー!私がしなければならなかった唯一の他のものは、拡張可能ではないので、基底クラスをクラス(およびケースクラスではない)にすることでした。 – ticofab

関連する問題