我想编写一个根据其类型参数表现不同的函数。我想要的一个简单示例如下所示:
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/ 。宏是在编译期间运行的自定义函数,可以根据编译时计算动态生成代码。