2016-11-08 6 views
0

私は、これらのパラメータがすべて同じ基本クラスから拡張されている場合、パラメータの型が異なる複数の異なるコンストラクタを持つクラスを持っています。Scala - コンストラクタ引数の実行時の型でコンストラクタを選択

は簡略化した例は、ここを参照してください:

abstract case class GeneralDataType() 
case class SpecificDataTypeOne() extends GeneralDataType 
case class SpecificDataTypeTwo() extends GeneralDataType 

case class MyNumber(myDataType: Int) extends { 
    def this(data: SpecificDataTypeOne) = this(1) 
    def this(data: SpecificDataTypeTwo) = this(2) 
} 

def getDataType(typeId: Int): GeneralDataType = typeId match { 
    case 1 => new SpecificDataTypeOne 
    case 2 => new SpecificDataTypeTwo 
} 

val x = getDataType(1) 

// error: Cannot resolve constructor 
val mn = new MyNumber(x) 

どのようにパラメータの種類に応じて、使用する正しいコンストラクタを選択するランタイムで?

+0

私はこれを取得していますエラー:caseクラスSpecificDataTypeOneは、祖先のGeneralDataTypeを持ちますが、大文字と小文字の継承は禁止されています。この制限を克服するには、抽出子を使用して、非リーフノードのパターンマッチングを行います。 –

答えて

1

他が示唆したように、工場とし​​てのコンパニオンオブジェクトを使用しよう(私はまだ私がコメントを追加しましたエラーを持っているが、それは依存Scalaのバージョンだかもしれない?)日食で

object MyNumber { 
    def apply(x:GeneralDataType) : MyNumber = x match { 
     case SpecificDataTypeOne() => new MyNumber(1) 
     case SpecificDataTypeTwo() => new MyNumber(2) 
    } 

    def getDataType(typeId: Int): GeneralDataType = typeId match { 
     case 1 => new SpecificDataTypeOne 
     case 2 => new SpecificDataTypeTwo 
    } 
    val x = getDataType(1) 
    val mn = MyNumber(x) 
} 
case class MyNumber(myDataType: Int) 


abstract case class GeneralDataType() 
    case class SpecificDataTypeOne() extends GeneralDataType 
    case class SpecificDataTypeTwo() extends GeneralDataType 
1

大文字と小文字は区別されません。コンパニオンオブジェクトはこの場合に使用できますが。

object MyNumber { 
    def apply(typeId: Int): MyNumber = typeId match { 
    case 1 => new MyNumber(new SpecificDataTypeOne) 
    case 2 => new MyNumber(new SpecificDataTypeTwo) 
    } 
} 

val mn = MyNumber(1) 
+0

こんにちは、私はあなたがその質問を誤解していると思います。 外部からタイプ(SpecificDataTypeOneまたはTwo)のいずれかのオブジェクトを取得し、そのタイプに基づいて適切なコンストラクターを呼び出したいとします。 –

0

あなただけの1 GeneralDataType(または多分少数)のためにそれを行う必要がある場合、いくつかのコンストラクタそれぞれ、パターンマッチングは何が必要でしょう。

x match { 
    case y1: SpecificDataTypeOne => new MyNumber(y1) 
    case y2: SpecificDataTypeTwo => new MyNumber(y2) 
} 

あなたは、より一般的にすることができますソリューションは反射を使用していますが、上記が十分でない場合にのみ使用してください。

+0

コードを格納するためにMyNumberのコンストラクタをオーバーロードしようとすると、動作しません... –

+0

'def this(data:GeneralDataType)= data match ...'のようなものですか?いいえ、それはしません。代わりにRockie Yangの答え(単に 'GeneralDataType'を引数に取る)のように、コンパニオンオブジェクトで' apply'メソッドを使用してください。 –

関連する問題