scala - 斯卡拉.reduce 泛型类型的奇怪行为
问题描述
我一直在想,为什么这段代码不会编译?
Scala中是否有一种方法可以创建通用参数化的方法/函数,并允许像“reduce”这样的操作。
这种行为是否与类型擦除有任何共同点,还是其他?我希望看到对此的广泛解释:)
def func2[B <: Int](data: Seq[B]): Unit = {
val operation = (a: B, b: B) => a.-(b)
data.reduce(operation)
}
编译器说:
type mismatch;
found : (B, B) => Int
required: (Int, Int) => Int
此外,本着同样的精神 - 总体上是否可以使用此方法在参数化集合上调用任何“类似流”的方法:
def func2[B <: Int](data: Seq[B]): Unit = {
val operation = (a: B, b: B) => a.-(b)
data.sum
}
还给出:
could not find implicit value for parameter num: Numeric[B]
解决方案
为什么我不能在集合类型上设置上限,并假设 B 类型(具有该约束)只有我需要的这些方法?
你的假设是正确的。您的上限B
使以下编译
val operation = (a: B, b: B) => a.-(b)
并且也reduce
可以在 a 上使用Seq[B]
,因为Seq
它是协变的。
由于编译器知道“ B
ISA Int
”,因此该-
方法存在于其上。但是,它仍然会返回一个Int
. 因为 的签名+
将返回类型限制为Int
def +(x: Int): Int
reduce
操作只能理解一种类型。所以如果你有
reduce[B](operation)
它将期望operation
是类型(B,B) => B
如果你有
reduce[Int](operation)
它将期望operation
是类型(Int,Int) => Int
您可以做的一件事是
val operation = (a: Int, b: Int) => a - b
这是安全的,因为您B
始终也是Int
推荐阅读
- ruby-on-rails - 找不到带有可执行导轨 (Gem::GemNotFoundException) 的 gem railties (>= 0.a)
- javascript - JS - 使用 lodash 删除数组中的重复对象
- c - 将#define 创建的宏传递给函数/数组
- azure - 在 Azure 中创建 VM 时,虚拟网络可以位于不同的资源组中吗
- javascript - 使 javascript 方法在所有情况下都有效(在 ajax 调用之前和之后)
- javascript - 使用 giphy API 获取数据到空数组并显示搜索结果
- ios - Swift3 在 collectionView 中添加一个按钮 Select / View
- android - 如何使用代码在多个活动中处理自定义工具栏中的按钮的“onClick”
- php - 获取 ACF 中页面的 ID
- javascript - 正则表达式 - 名称中只允许一个空格和一个连字符