无法理解Scala中的类型错误

时间:2009-09-23 10:10:39

标签: scala

这是POC代码:

object TypeTest extends Application {
    val stuff = List(1,2,3,4,5)
    def joined:String = stuff.reduceLeft(_ + ", " + _)

    println(joined)
}                                                                                             

编译时,会出现以下错误:

tt.scala:4: error: type mismatch;
 found   : java.lang.String
 required: Int
    def joined:String = stuff.reduceLeft(_ + ", " + _)
                                                      ^
tt.scala:4: error: type mismatch;
 found   : Int
 required: String
    def joined:String = stuff.reduceLeft(_ + ", " + _)
                                  ^

编写连接函数,如

reduceLeft(_.toString + ", " + _.toString)

没有帮助,仍然会出现同样的错误。但是,如果我像

那样写
def joined:String = stuff.map(_.toString).reduceLeft(_ + ", " + _)

一切都很好。

有人可以解释这种奇怪的类型错误组合吗?这是怎么回事?第二个特别奇怪,因为Int到String的隐式转换。

2 个答案:

答案 0 :(得分:9)

reduceLeft要求功能块(在括号内)返回与集合相同的类型。这是因为以递归方式调用块,直到消耗了集合的所有值。

stuff是List [Int],但是(_ +“,”+ _)是一个String,因此类型错误。

与reduceLeft类似的方法是foldLeft。区别在于集合类型和结果类型可以不同。例如:

stuff.foldLeft("") { _ + ", " + _ } // => java.lang.String = , 1, 2, 3, 4

我猜你的例子是指示性的,但如果你真的想要一个逗号分隔值的字符串,那么以下会更好:

stuff.mkString(", ") // => String = 1, 2, 3, 4

答案 1 :(得分:1)

我也开始使用Scala了。这就是我的理解。

'stuff'是一个Int列表,因此'reduceLeft'需要一个Int参数并返回一个Int(基于this)。但是您将字符串作为参数(错误1)并尝试将结果分配给字符串(错误2)。这就是你犯这样错误的原因。