这是一个简单的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"
答案 0 :(得分:5)
fold
的签名是:
def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1
折叠操作的两个操作数(op
)必须属于同一类型,但在您的情况下它们是String
和(String, String)
,因此编译器会尝试查找两种类型之间的最小上限,并找到Serializable
。
foldLeft
和foldRight
允许累加器和下一个元素是不同的类型,因此这些可以工作。
scala> x.foldLeft("") { case (acc, (k, v)) => acc + s""", "$k":"$v"""" }
res8: String = , "a":"a", "b":"b"
折叠并不是你想要的,但是,除非你特别处理,否则你最终会得到额外的逗号。相反,您可以使用map
和mkString
。
scala> x.map { case (k, v) => s""""$k":"$v"""" }.mkString(", ")
res10: String = "a":"a", "b":"b"
我也删除了类型归属,因为它们不是必需的。