错误。您收到编译时错误,因为签名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 的折叠值。这些处理器产生的结果必须组合成一个最终的折叠值——这是使用函数完成的,它就是这样做的。A1opop
现在,请注意,这不能使用fin完成foldLeft,因为每个处理器都会产生类型的折叠值B。B不能使用 组合多个类型的值f,因为f只能将值B与另一个类型的值组合 - 类型和A之间没有对应关系。AB
例子。在您的示例中,假设第一个处理器采用元素"1", "2",第二个处理器采用 element "3"。第一个将产生折叠值3,第二个将产生另一个折叠值3。现在他们必须结合他们的结果来获得最终的折叠值——这是不可能的,因为闭包_ + _.toInt只知道如何结合一个IntandString而不是 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用作中性元素,但不能用作非空列表。