gpt4 book ai didi

scala - 将数字相加

转载 作者:行者123 更新时间:2023-12-04 14:18:24 24 4
gpt4 key购买 nike

我有一个列表[编号]。它包含 Number 不同子类的值 - Int、Double 等。我想把所有的值加在一起。如果列表只包含 Int,我希望结果是一个 Int。如果有混合,我想遵循正常的 Scala 规则: Int + Double = Double (等等)。

我试过这个:

val result = list.reduceLeft(_ + _)

这甚至无法编译。 Number 没有定义采用另一个 Number 的 + 方法。

我怎样才能做到这一点?

安德烈斯

最佳答案

从第一次提出问题的 Scala 邮件列表中复制我的答案:
Number是一个 Java 类,除了将自身转换为原始类型之外没有其他功能。不幸的是,Scala 的 AnyVal除了标记原始类型之外不做任何事情,并且 Numeric[T] from Scala 只知道它自己的类型,而不知道类型的混合。

所以你留下了相当不愉快的模式匹配;如果您确定只需要处理 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,因为实际上并没有删除 float 以保持 long 的大部分数值精度,然后做 MyDouble(value.toDouble + f.toDouble) ,例如。

这一切都相当尴尬; Java 和 Scala 都没有真正提供对混合类型数学的支持。

关于scala - 将数字相加,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6397634/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com