scala – 基于泛型类型的函数,根据类型对数字求和
假设x和y具有相同的类型,可以是Boolean,Int或Double.这是我想写的函数:
f(x,y) = - if x == Boolean ==> !x - if x == Integer or x == Double ==> x+ y 这样做的一种方法可以是以下方法.我想知道是否有人对此有更好的想法. def fun[T](x: T,y: T): T { x match { case xP: Boolean => !xP case xP: Double => y match { case yP: Double => xP + yP } case xP: Int => y match { case yP: Int => xP + yP } } } 我对此不满意的原因是x和y具有相同的类型.我不应该需要两个匹配案例;对? 另外两件事: >仅仅设置[T<:Int,Double,Boolean]就可以将类型限制为仅三种类型了吗? 解决方法
这正是类型类旨在解决的问题.在你的情况下你可以写这样的东西:
trait Add[A] { def apply(a: A,b: A): A } object Add { implicit val booleanAdd: Add[Boolean] = new Add[Boolean] { def apply(a: Boolean,b: Boolean): Boolean = !a } implicit def numericAdd[A: Numeric]: Add[A] = new Add[A] { def apply(a: A,b: A): A = implicitly[Numeric[A]].plus(a,b) } } Add [X]类型的值描述了如何添加两个类型为X的值.您可以在每个要执行此操作的类型X的范围内放置Add [X]类型的隐式“实例”.在这种情况下,我为Boolean和任何具有scala.math.Numeric实例(由标准库提供的类型类)的类型提供了实例.如果你只想要Int和Double的实例,你可以简单地省略numericAdd并编写你自己的Add [Int]和Add [Double]实例. 你会像这样写下你的乐趣: def fun[T: Add](x: T,y: T) = implicitly[Add[T]].apply(x,y) 并像这样使用它: scala> fun(true,false) res0: Boolean = false scala> fun(1,2) res1: Int = 3 scala> fun(0.01,1.01) res2: Double = 1.02 这具有非常显着的优点,即在运行时不会在尚未定义操作的类型上爆炸.如果您传递了例如MatchError异常,则不会使程序崩溃两个字符串很有趣,你得到一个很好的编译失败: scala> fun("a","b") <console>:14: error: could not find implicit value for evidence parameter of type Add[String] fun("a","b") ^ 一般来说,“类型大小写”匹配(即看起来像x:X => …的匹配)在Scala中是一个坏主意,而且几乎总有一个更好的解决方案.通常它会涉及类型类. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |