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

scala – 一起添加数字

发布时间:2020-12-16 18:52:33 所属栏目:安全 来源:网络整理
导读:我有一个List [Number].它包含Number – Int,Double等不同子类的值.我想把所有的价值加在一起.如果列表只包含Int,我希望结果是Int.如果有混音,我想遵循正常的 Scala规则:Int Double = Double(依此类推). 我试过这个: val result = list.reduceLeft(_ + _)
我有一个List [Number].它包含Number – Int,Double等不同子类的值.我想把所有的价值加在一起.如果列表只包含Int,我希望结果是Int.如果有混音,我想遵循正常的 Scala规则:Int Double = Double(依此类推).

我试过这个:

val result = list.reduceLeft(_ + _)

这甚至不可编译. Number没有定义另一个Number的方法.

我怎么能做到这一点?

安德烈斯

解决方法

从首次提出问题的Scala邮件列表中复制我的答案:

Number是一个Java类,除了将自身转换为基本类型之外没有任何功能.不幸的是,除了标记原始类型之外,Scala的AnyVal没有做任何事情,而Scala的Numeric [T]只知道它自己的类型,而不是类型的混合.

所以你留下了相当不愉快的模式匹配;最短的语法,如果你确定你只需要处理double和int是:

list.reduceLeft((l,r) => (l: Any,r: Any) match {
  case (li: Int,ri: Int) => li + ri
  case _ => l.doubleValue + r.doubleValue
})

请注意,我正在向Any转换以获取Scala模式匹配,以便为我们执行拆箱操作;如果你把它保留为Number,你必须在java.lang.Integer上进行模式匹配然后valueOf它,这很痛苦.

如果你想要更多,你必须建立适当的促销活动:

list.reduceLeft((l,r) => (l: Any) match {
  case li: Int => (r: Any) match {
    case ri: Int => li + ri
    case rf: Float => li + rf
    case rl: Long => li + rl
    case _ => li + r.doubleValue
  }
  case lf: Float => /* etc. */
})

如果你不得不这么做,你可能最好放弃Numeric,转而使用自己的包装类,这些类知道如何将自己与适当的促销相结合;那么你可以只编写一次匹配模式并返回到列表推导中使用.

sealed abstract class Addable {
  def +(a: Addable): Addable
}

final case class MyInt(value: Int) extends Addable {
  def +(a: Addable) = a match {
    case MyInt(i) => MyInt(value + i)
    case MyFloat(f) => MyFloat(value + f)
    ...
  }
}

final case class MyFloat(value: Float) extends Addable {
  def +(a: Addable) = a match {
    case MyInt(i) => MyFloat(value + i)
    ...
  }
}

...

这种方法的一个小优点是你可以决定以不同于标准的方式提升值(例如,你可能会认为float long = double,因为浮点确实没有被删除以保持很长的数值精度,例如,做MyDouble(value.toDouble f.toDouble).

这一切都很尴尬; Java和Scala都不能真正为混合型数学提供支持.

(编辑:李大同)

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

    推荐文章
      热点阅读