为什么scalac抱怨String上的method +?

时间:2011-09-18 17:54:10

标签: scala types

给出以下Scala代码:

def stream(callback: (String, Array[Byte]) => Unit) {
    callback("application/json;charset=utf-8", Array(1))
    callback("application/xml;charset=utf-8", Array(1))
}

@Test
def whenStreaming_thenShouldSeeSameMessages() {
    var actualMessages = List.empty[(String, Array[Byte])]
    sut.stream {
        (contentType, payload) =>
            actualMessages += (contentType, payload)
    }

    expect(List("application/json;charset=utf-8", "application/xml;charset=utf-8")) {
        actualMessages
    }
}

为什么我收到以下错误消息:

error: too many arguments for method +: (other: String)java.lang.String
actualMessages += (contentType, payload)

具体而言,有效负载在IDEA中突出显示,在命令行中,+ =突出显示。我真的不明白这个错误信息。

1 个答案:

答案 0 :(得分:6)

使用附加元素创建新列表的方法实际上是:+。要使用附加版本更新列表var,您需要执行

actualMessages :+= (contentType, payload)

或者你可以用前缀

actualMessages +:= (contentType, payload)
// or, equivalently,
// actualMessages ::= (contentType, payload)

(对于大型列表,预先添加实际上是可取的,因为它是O(1)与O(n)相比用于追加。一种策略是使用前置来反向构建列表,然后在结束时调用{{1 }}。)

使用您尝试使用的List.reverse运算符,Scala认为您想要进行字符串连接,

+

这是Java的遗憾结转。使用scala.Predef

中定义的隐式转换在Scala中实现通用字符串连接
scala> List("hello") + " world"
res0: java.lang.String = List(hello) world

正在发生的事情是implicit def any2stringadd (x: Any): StringAdd 没有实现List方法,因此编译器会查找转换为提供+的内容,并找到+。这是例如any2stringadd的工作方式。