错误。您收到编译时错误,因为签名fold
仅允许折叠类型的值,该类型是集合中值类型的超类型,并且是String
(您的集合类型)和Int
(您提供的零的类型)的唯一超类型元素)是Any
。因此,折叠结果的类型被推断为Any
- 并且Any
没有方法toInt
。
请注意,两个版本的fold
签名不同:
fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1
foldLeft[B](z: B)(f: (B, A) => B): B
为什么他们有不同的签名?这是因为fold
可以并行实现,就像并行集合一样。当多个处理器折叠集合中的值时,每个处理器都会获取 type 元素的子集,并通过连续应用来A
生成 type 的折叠值。这些处理器产生的结果必须组合成一个最终的折叠值——这是使用函数完成的,它就是这样做的。A1
op
op
现在,请注意,这不能使用f
in完成foldLeft
,因为每个处理器都会产生类型的折叠值B
。B
不能使用 组合多个类型的值f
,因为f
只能将值B
与另一个类型的值组合 - 类型和A
之间没有对应关系。A
B
例子。在您的示例中,假设第一个处理器采用元素"1", "2"
,第二个处理器采用 element "3"
。第一个将产生折叠值3
,第二个将产生另一个折叠值3
。现在他们必须结合他们的结果来获得最终的折叠值——这是不可能的,因为闭包_ + _.toInt
只知道如何结合一个Int
andString
而不是 2 个Int
值。
对于这些类型不同的情况,请使用aggregate
,其中您必须定义如何组合 type 的两个值B
:
def aggregate[B](z: B)(seqop: (B, A) => B, combop: (B, B) => B): B
上面定义了当combop
折叠结果和集合中的元素具有不同类型时如何做最后一步。
中性元素。如上所述,多个处理器可以折叠集合中的元素子集。它们中的每一个都将通过添加中性元素来开始其折叠值。
在以下示例中:
List(1, 2, 3).foldLeft(4)(_ + _)
总是返回10 = 4 + 1 + 2 + 3
。
但是,4
不应与 一起使用fold
,因为它不是中性元素:
List(1, 2, 3).fold(4)(_ + _)
以上可能返回(4 + 1 + 2) + (4 + 3) = 14
或(4 + 1) + (4 + 2) + (4 + 3) = 18
。如果您不对 使用中性元素fold
,则结果是不确定的。同理,您可以将Nil
用作中性元素,但不能用作非空列表。