我试着计算字符串的unicode" Hello"在斯卡拉。在StringOps scala API中,我找到了fold和foldLeft方法,并使用上述两种方法编写了一些代码:
val s = "Hello"
s.fold(1L){(z, i) => z*i}
s.foldLeft(1L){(z, i) => z*i}
通过使用第二个表达式,我可以得到正确的答案,但第一个不能和IDE抱怨"无法解析符号*",任何人都可以解释这个吗?
答案 0 :(得分:2)
如果查看fold
的类型签名:
fold[A1 >: Char](z: A1)(op: (A1, A1) ⇒ A1): A1
你会发现它只对Char
的超类型进行操作,因此使你的表达式无法进行,编译器会抛出错误。
foldLeft
允许您使用结果类型B
foldLeft[B](z: B)(op: (B, Char) ⇒ B): B
这允许您编写当前表达式。
总结一下:fold
期望Char
作为其种子参数(当您提供1L
作为编译器将抱怨的种子时),而foldLeft
期望生成的类型您的op
功能。
<强>更新强>
编译器也认为 s.fold(1L){(z, i) => z}
是正确的。这是因为Char
和Long
共享超类型AnyVal
。由于fold
期望提供Char
的超类型AnyVal
也有效。这也是编译器抱怨它无法找到函数*
的原因,因为它没有在类型AnyVal
上定义。
更新2:
如果您真的想使用fold
代替foldLeft
,则必须事先将s
映射到Seq [Long]。即:
s.map(_.toLong).fold(1L){(z, i) => z*i} //returns 9415087488