【问题标题】:Can't understand type errors in Scala无法理解 Scala 中的类型错误
【发布时间】:2009-09-23 10:10:38
【问题描述】:

这里是 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 的隐式转换。

【问题讨论】:

    标签: scala


    【解决方案1】:

    reduceLeft 要求函数块(在括号内)返回与集合相同的类型。这是因为 block 是递归调用的,直到集合的所有值都被消耗完。

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

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

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

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 2020-02-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-17
        • 1970-01-01
        • 2015-08-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多