加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 基于泛型类型的函数,根据类型对数字求和

发布时间:2020-12-16 18:44:24 所属栏目:安全 来源:网络整理
导读:假设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 mat
假设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]就可以将类型限制为仅三种类型了吗?
>输出类型需要再次为T.

解决方法

这正是类型类旨在解决的问题.在你的情况下你可以写这样的东西:

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中是一个坏主意,而且几乎总有一个更好的解决方案.通常它会涉及类型类.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读