为什么fold操作的返回类型是Serializable而不是String

时间:2016-12-21 00:19:11

标签: scala

这是一个简单的scala代码

scala> val x = scala.collection.immutable.TreeMap[String, String]("a"->"a", "b"->"b")
x: scala.collection.immutable.TreeMap[String,String] = Map(a -> a, b -> b)
scala> val y = x.fold(""){case (acc: String, (k: String, v: String)) => acc + s""", "$k":"$v""""}
y: java.io.Serializable = , "a":"a", "b":"b"

为什么返回类型y不是String而是java.io.Serializable?

我认为可能是因为我正在使用模式匹配,而且匹配可能并非详尽无遗。所以我将代码更改为

scala> val y = x.fold(""){case (acc: String, (k:String, v:String)) => acc + s""", "$k":"$v"""" case _ => ""}
y: java.io.Serializable = , "a":"a", "b":"b"

1 个答案:

答案 0 :(得分:5)

fold的签名是:

def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1

折叠操作的两个操作数(op)必须属于同一类型,但在您的情况下它们是String(String, String),因此编译器会尝试查找两种类型之间的最小上限,并找到Serializable

foldLeftfoldRight允许累加器和下一个元素是不同的类型,因此这些可以工作。

scala> x.foldLeft("") { case (acc, (k, v)) => acc + s""", "$k":"$v"""" }
res8: String = , "a":"a", "b":"b"

折叠并不是你想要的,但是,除非你特别处理,否则你最终会得到额外的逗号。相反,您可以使用mapmkString

scala> x.map { case (k, v) =>  s""""$k":"$v"""" }.mkString(", ")
res10: String = "a":"a", "b":"b"

我也删除了类型归属,因为它们不是必需的。