型パラメーターに応じて異なる動作をする関数を作成したいと考えています。私が欲しいものの簡単な例を以下に示します。
def f[Int] = "I'm an int"
def f[Float] = "I'm a float"
def f[Burger] = "You want fries with that?"
これは Scala で可能ですか、それとも何らかの回避策が必要ですか?
型パラメーターに応じて異なる動作をする関数を作成したいと考えています。私が欲しいものの簡単な例を以下に示します。
def f[Int] = "I'm an int"
def f[Float] = "I'm a float"
def f[Burger] = "You want fries with that?"
これは Scala で可能ですか、それとも何らかの回避策が必要ですか?
直接ではありません。Scala でこれを行う通常の方法は、型クラスを使用することです。
trait FAble[T] { def doF: String }
object FAble {
implicit val fInt = new FAble[Int] { def doF = "I'm an int" }
implicit val fFloat = new FAble[Float] { def doF = "I'm a float" }
implicit val fBurger = new FAble[Burger] { def doF = "You want fries?" }
}
def f[T](implicit ev: FAble[T]) = ev.doF
// or
def f[T: FAble] = implicitly[FAble[T]].doF
これはかなり冗長ですが、いくつかの利点もあります - 暗黙のインスタンスは ( implicit def
s の代わりにval
s を使用して) 計算でき、任意の型に対して複数のインスタンスが存在する可能性があります。コードのさまざまなポイントでスコープ内のさまざまなインスタンス。
C++ の方法でそれを行うことができない理由は、Scala ジェネリックがさまざまな型パラメーターのコード生成を必要としないためです (@specialized
さておき、それはあなたが望むこともしないためです)。したがって、「コンパイラさん、その位置に Int がある場合は、汎用テンプレートからコードを生成する代わりに、この特定のコードを使用してください」と言うのは意味がありません。
別の可能なアプローチは、証拠を使用することです。
def f[T](t:T)(implicit ev: T<:<Float) {
// float version
}
def f[T](t:T)(implicit ev: T<:<Int) {
// int version
}
ただし、よりエレガントなソリューションとして型クラスをお勧めします
マクロを調べることをお勧めします:http ://scalamacros.org/ 。マクロは、コンパイル中に実行されるカスタム関数であり、コンパイル時の計算に基づいて動的にコードを生成できます。