2017-02-14 6 views
0

モデルの名前を持つ文字列を取得し、そのケースクラスのインスタンスを返す関数がありますが、この関数で動的戻り型を使用する正しい方法は何ですか?スカラ関数で動的戻り型を使用する

case class Person(fname: String, lname: String) 
case class Animal(type: String, weight: Double) 

def getInstanceOf(model: String): ??? = model match { 
    case "person" => Person("jack", "robinson") 
    case "animal" => Animal("lion", 190.0) 
} 

ありがとうございます!

+1

を説明した場合、答えるために容易になるだろうと思いますタイプ固有のメソッドにアクセスするには、特定のタイプにキャストする必要があります。一般に、無関係の型を単一のメソッドから返すのは悪い考えです。 – jwvh

+0

コンパイル時に実行時まで存在しない情報も知ることはできません。型はコンパイル時の概念です。 –

答えて

3

それは少しより多くのコンテキストを持ってするのを助けることができます最終目標は解決策を提案するためのものです。

お使いのモデルがすべて特定の分類に準拠していて、それらがどのようなインスタンスであるかを正確に知る必要がない場合は、上記のabstract class(またはtrait)の提案が有効です。

EDIT:

あなたはまた、一般的な戻り値の型を作ると、このシナリオでは、その上に型境界を置くことができる、など:

def getInstanceOf[T <: Living](model: String): T = ... 

しかし、指摘のように私のオリジナルの答えは、このスニペットを含めこれにより、呼び出し元は、model引数に含まれている内容を打ち消す可能性のあるタイプを指定することができます。

2つのタイプのうちの1つを返すだけですが、正確なタイプが必要な場合はEither[T1, T2]はここに適切であるような(http://www.scala-lang.org/api/current/scala/util/Either.html):

def getInstanceOf(model: String): Either[Person, Animal] = ... 

しかし、再び、私は最終目標は、あなたが可能なすべての基本クラスを考え出すことができビット

+0

'def getInstanceOf [T <:Living](model:String):T = ...'は、 'model'の値に応じて、呼び出し側が' T'を選択するという意味で、 –

+0

@Alexey Romanovそれは実際には大きなポイントです。私はこれを呼び出すために私の答えを更新します – MattEdge

6

たぶん、あなたは抽象クラスを定義し、それから、両方のクラスを拡張し、その後、あなたは戻り値の型として抽象クラスを指定することができますすることができます

abstract class Living 

case class Person(fname: String, lname: String) extends Living 
case class Animal(Type: String, weight: Double) extends Living 

def getInstanceOf(model: String): Living = model match { 
    case "person" => Person("jack", "robinson") 
    case "animal" => Animal("lion", 190.0) 
} 
// getInstanceOf: (model: String)Living 
関連する問題