2017-11-19 20 views
0

注:誰かが私が尋ねようとしているもののより良いタイトルを考え出すことができる場合は、言及するか編集してください。私はMyWrapperBoundのすべてのすべての実装は、私は私のwrapメソッドからそれを構築し、返すことができmessage: Stringを取るコンストラクタを持つべきであることを記述するための方法を探していますコンストラクタの境界?

​​

:ラップ法を考える

私はこれを行うにはいくつかの方法を考えることができます。

方法1 - 暗黙的に使用して:

def wrap[T <: MyWrapperBound](message: String)(implicit factory: String => T): T 

これは、任意のMyWrapperBound IMPLことを意味します。

case class SimpleBound(message: String) extends MyWrapperBound 

object SimpleBound { 
    implicit def factory(message: String): SimpleBound = SimpleBound(message) 
} 

これにより、かなりの量の定型文が生成されますが、これは避けたいものです。

方法2 - マクロ:開発者のために存在しない場合

def wrap[T <: MyWrapperBound](message: String): T = macro ... 

マクロは、種類を取るのがあれば種類を構築し、有効なコンストラクタがある主張と素敵なコンパイルエラーをスローします

私の質問は、スカラには新しく、欠けている簡単なオプションはありますか?より意味のある別のオプションがありますか?

+0

方法1と方法2は異なるものです。方法1では、暗黙的にそれを実装する方法について話し、方法2では、マクロを使用して検証を行う方法について説明します。方法2のマクロを使って型のコンストラクタを生成したいと言っていましたか? –

+0

はい、同じ目標を達成するさまざまな方法です。メソッド2はコンストラクターが既に存在する場合にのみコンストラクターを検証して使用します。それがなければ、コンパイル時エラーを修正するためにそれを追加して追加するのは開発者次第です。 – Cheetah

+0

@YuvalItzchakov - あなたのコメントにつながったと私が思った間違いを見ました。マクロバージョンは、暗黙的なパラメータを持つことを意図していませんでした....ごめんなさい。 – Cheetah

答えて

0

あなたがタイプメスに適しているのであれば、暗黙のうちに少し簡単な答えがあります。あなたは、タイプパラメータをMyWrapperBoundに追加し、Showタイプキャストを使用してサポートしたいメッセージのタイプを列挙することで、簡単にやろうとしていることを達成できます。あなたがマップA => Stringをサポートラップしようとしていたすべてのものを知っていた場合たとえば、あなたはそうのようなあなたのwrap方法にShow[A]暗黙的に供給することができます:

trait Show[A] { 

    def show(a: A): String 
} 

trait MyWrapperBound[A] { 

    val message: String 

} 

object MyWrapperBound { 

    def wrap[A](a: => A)(implicit ev: Show[A]): MyWrapperBound[A] = 
    new MyWrapperBound[A] { 
     override val message: String = ev.show(a) 
    } 
} 

object ShowInstances { 

    case class MyDS(someInformation: List[String]) 

    implicit val simpleShow: Show[String] = new Show[String] { 
    override def show(a: String): String = a 
    } 

    implicit val slightlyMoreComplexShow: Show[MyDS] = new Show[MyDS] { 
    override def show(a: MyDS): String = a.someInformation.mkString("[", ",", "]") 
    } 
} 

はいつものように、コードがコンパイルされ、所望の出力を生成します。より多くのサポートを追加するのは、ShowInstancesにインスタンスを追加するのと同じくらい簡単です。これにより、wrapMyWrapperBoundの単純なコンストラクタになるように、マップA => Stringをラッパーロジック自体から切り離すことができます。

タイプパラメータでMyWrapperBoundをパラメータ化するのが気に入らない場合は、メッセージタイプによってインスタンスのインデックスを作成する予定がない場合でも必要ありません。