斯卡拉" a" + _.toString的行为不像" a"。+(_。toString)

时间:2012-07-03 12:49:43

标签: scala

据我所知,Scala中的中缀运算符用法应该等同于方法的调用。所以:

scala> "a" + 3.toString
res0: java.lang.String = a3

与:

相同
scala> "a".+(3.toString) 
res1: java.lang.String = a3

当遇到占位符时,我遇到了没有发生这种情况的场合。我正在做一些更复杂的事情,但它可以被提炼为:

scala> def x(f:(Int)=>String) = f(3)
x: (f: Int => String)String
scala> x("a" + _.toString)
res3: String = a3

到目前为止一切顺利。但...

scala> x("a".+(_.toString))
<console>:9: error: missing parameter type for expanded function ((x$1) => x$1.toString)
          x("a".+(_.toString))

这有什么区别?我错过了什么?

霍尔迪阿

2 个答案:

答案 0 :(得分:11)

_占位符只能出现在其功能的最顶层Expr。这意味着

(_.toString)

本身就是一个函数,"a" + some function of unknown type对编译器没有多大意义。

答案 1 :(得分:10)

您对中缀符号的评估是正确的,但您对占位符参数的理解存在缺陷。

使用下划线作为占位符参数时,您正在创建一个函数。问题是该函数的边界是什么:它从哪里开始,它在哪里结束?例如,请考虑以下表达式:

_ + _ + _

应该如何翻译?以下是一些替代方案:

(x, y, z) => { x + y + z }
(x, y) => { (z) => { x + y } + z }
(x) => { x + { (y, z) => y + z } }

嗯,Scala规则是范围是最里面的括号分隔表达式,否则是整个表达式。所以,在实践中,你写了两个不同的东西:

x("a" + _.toString) // is the same thing as
x((y) => "a" + y.toString)

x("a".+(_.toString)) // is the same thing as
x("a".+((y) => y.toString))