Scala 在尾部递归函数中使用Nil作为初始累加器
回答说Scala 在尾部递归函数中使用Nil作为初始累加器,scala,null,accumulator,Scala,Null,Accumulator,回答说Nil不能用作折叠的初始累加器 不使用Nil作为初始累加器值 scala> xs res9: List[Int] = List(1, 2, 3) scala> xs.foldLeft(Nil)( (acc, elem) => elem.toString :: acc) <console>:9: error: type mismatch; found : List[String] required: scala.collection.immutable
Nil
不能用作折叠的初始累加器
不使用Nil
作为初始累加器值
scala> xs
res9: List[Int] = List(1, 2, 3)
scala> xs.foldLeft(Nil)( (acc, elem) => elem.toString :: acc)
<console>:9: error: type mismatch;
found : List[String]
required: scala.collection.immutable.Nil.type
xs.foldLeft(Nil)( (acc, elem) => elem.toString :: acc)
但是为什么我可以在下面的尾部递归函数中使用Nil
scala> def toStringList(as: List[Int]): List[String] = {
| def go(bs: List[Int], acc: List[String]): List[String]= bs match {
| case Nil => acc
| case x :: xs => go(xs, x.toString :: acc)
| }
| println(as)
| go(as, Nil)
| }
toStringList: (as: List[Int])List[String]
问题是Scala从第一个参数列表开始类型推断。因此给定def foldLeft[B](z:B)(f:(B,A)=>B):B
和
xs.foldLeft(Nil)(...)
它将B
推断为Nil.type
(只有一个值的类型:Nil
),并使用该类型检查第二个参数列表,该列表显然失败。但是,List[String]()
具有类型List[String]
,因此B
是List[String]
,它将与f
一起使用。另一种解决方法是显式写入类型参数:
xs.foldLeft[List[String]](Nil)(...)
在第二个程序中,acc
的类型是给定的(并且必须是,因为它是一个函数参数),因此不会发生与初始问题对应的类型推断。Nil
(本身)是一个(空的)列表[无]
,其中as列表[字符串]()
或列表。空的[字符串]
是空列表(显然)对于元素类型String
.Ah,@RandallSchulz-,因为列表在Scala中是协变的,这使得Scala.collection.immutable.Nil成为列表[T]的一个实例,对于类型为T的任何元素。
-。谢谢。foldLeft
的签名是def foldLeft[B](z:B)(f:(B,A)=>B):B
和方法签名没有差异。如果你从开始什么都不做
,那就是你所能拥有的一切。没有什么都没有!如果您想在折叠中使用Nil
进行累加,只需添加类型归属:xs.foldRight(Nil:List[String])(::u)。
xs.foldLeft[List[String]](Nil)(...)