【问题标题】:What's wrong with this piece of scala code?这段 scala 代码有什么问题?
【发布时间】:2016-07-02 00:32:09
【问题描述】:

我有以下无法编译的代码sn-p:

val cids = List(1, 2, 3, 4)
val b = Map.newBuilder[Int, Int]
for (c <- cids) {
  b += (c, c*2)
}
b.result()

编译器报告

console>:11: error: type mismatch;
 found   : Int
 required: (Int, Int)
               b += (c, c*2)

我不知道是什么错误。

【问题讨论】:

    标签: scala


    【解决方案1】:

    这可行:

    for (c <- cids) {
       b += ((c, c*2))
    }
    

    编译器将括号解析为+= 函数的参数列表括号,而不是元组。添加嵌套括号意味着将元组作为参数传递。它令人困惑...

    【讨论】:

    • 规范中有提到这个吗?应该如何知道它何时被解释为元组以及何时被解释为参数列表?
    • 这太令人困惑了,这个答案有点错误。这不是解析问题,而是表达式的输入方式有问题。
    • @YuvalItzchakov "auto-tupling" 从未在规范中提及。该更改存在问题,但我不知道是否添加了它。 “太混乱了……”,他们想摆脱它。 issues.scala-lang.org/browse/SI-3583
    【解决方案2】:

    您可以通过以下方式修复它:

    b += (c->c*2)
    

    【讨论】:

    • b += (c, c*2).x
    【解决方案3】:

    这是一个重复的问题。

    通常,提供一个未元组的 arg 列表如图所示,但是当方法重载时它不起作用,因为它会选择你不想要的方法,并且不会费心尝试自动元组你的 args。

    scala> class C[A] { def f(a: A) = 42 }
    defined class C
    
    scala> val c = new C[(String, Int)]
    c: C[(String, Int)] = C@3a022576
    
    scala> c.f("1", 1)
    res0: Int = 42
    
    scala> class C[A] { def f(a: A) = 42 ; def f(a: A, b: A, rest: A*) = 17 }
    defined class C
    
    scala> val c = new C[(String, Int)]
    c: C[(String, Int)] = C@f9cab00
    
    scala> c.f("1", 1)
    <console>:14: error: type mismatch;
     found   : String("1")
     required: (String, Int)
           c.f("1", 1)
               ^
    

    【讨论】:

      【解决方案4】:

      一种使用(不可变)值的方法,

      (cids zip cids.map(_ * 2)).toMap
      

      使用zip,我们将每个值与其双精度值配对,结果列表转换为Map

      【讨论】:

        【解决方案5】:

        如果你去文档,你会发现:this

        支持的 API 是 ms += (k -&gt; v) 。那就是你需要使用

        for (c <- cids) {
          b += (c -> c*2)
        }
        

        您也可以使用上面建议的((c, c*2)) 语法。发生这种情况是因为编译器无法知道括号是用于元组的。它只是将该参数理解为传递给 += 方法的两个参数。

        【讨论】:

        • 这不准确,您可以向地图添加元组。从您发布的链接中:“... Map("x" -> 24, "y" -> 25, "z" -> 26) 与 Map(("x", 24), (" y", 25), ("z", 26))" - 两者是等价的。在这个特定的例子中,编译器错误地解释了括号,因为使用了+= infix 方法;问题是 id 没有(c, c*2) 解释为元组。
        • @TzachZohar 我不认为中缀语法是相关的。但是有问题的 API 本身是mutable.Builder。所以该链接具有误导性。
        猜你喜欢
        • 2015-04-25
        • 2018-09-09
        相关资源
        最近更新 更多