【发布时间】:2013-08-07 16:39:44
【问题描述】:
我对以下行为感到困惑 - 为什么使用 math.max 减少 Int 数组有效,但 Float 数组需要包装函数?我记得这在 2.9 中不是问题,但我对此并不完全确定。
$ scala -version
Scala code runner version 2.10.2 -- Copyright 2002-2013, LAMP/EPFL
$ scala
scala> import scala.math._
scala> Array(1, 2, 4).reduce(max)
res47: Int = 4
scala> Array(1f, 3f, 4f).reduce(max)
<console>:12: error: type mismatch;
found : (Int, Int) => Int
required: (AnyVal, AnyVal) => AnyVal
Array(1f, 3f, 4f).reduce(max)
^
scala> def fmax(a: Float, b: Float) = max(a, b)
fmax: (a: Float, b: Float)Float
scala> Array(1f, 3f, 4f).reduce(fmax)
res45: Float = 4.0
更新:这确实有效
scala> Array(1f, 2f, 3f).reduce{(x,y) => math.max(x,y)}
res2: Float = 3.0
那么只有reduce(math.max)不能简写?
【问题讨论】:
-
不知何故
reduce的类型参数被推断为AnyVal。作为一种解决方法,您可以明确声明:Array(1f, 2f, 4f).reduce[Float](math.max) -
这是由方法重载引起的(再次......)。如果您添加另一个
fmax但使用Ints,那么您的reduce(fmax)也会停止工作。 -
哇,刚刚注意到虽然
Array(1f, 2f, 3f).reduce(max)无法编译,但以下工作:Array(1f, 2f, 3f).reduce(max(_,_))。我什至没有添加任何额外的类型注释。叫我大吃一惊。 -
那是因为
Array(1f, 2f, 3f).reduce((x,y) => max(x,y))有效。我能看到的唯一区别是重载解析在应用时的执行方式不同(max(x,y)),而不是作为函数值(eta-expansion + 解析为reduce的参数的类型)。可悲的是,后者在规范中没有很好地描述...... -
噢!我什至没有注意到 OP 的更新显示
reduce{(x,y) => math.max(x,y)}有效。这种类型推断行为的差异真的很不幸。
标签: scala scala-2.10