scala coalesces multiple function call parameters into a Tuple -- can this be disabled?讨论了Scala创建一个绑定到一个arg函数的元组。这导致
scala> println(1, 2)
(1,2)
答案说编译器允许在没有parens的情况下调用一个arg函数,因此逻辑上这是对带有元组的println的调用。
但是使用单个元组参数
无法调用printlnscala> val t = (1, 2)
t: (Int, Int) = (1,2)
scala> println t
<console>:6: error: value t is not a member of Unit
println t
^
所以其他事情正在发生。为什么元组在这里很特别?
答案 0 :(得分:15)
相反,this explanation,Scala的解析 println(1,2)
(或Console println (1,2)
对于这个问题)它解析任何两个参数的方法调用的方法相同。稍后,编译器通过将方法参数包装在元组中来匹配实际的方法类型签名来转换调用。
如果编译器没有这样做,那么像Console println (1,2)
这样完全有效的表达式将无法编译,因为println
不会带多个参数。此行为也有other valid use cases。
从编译器的角度考虑类似foo bar (1,2)
的表达式,请记住Scala具有特殊的语法,允许您删除方法调用上的.
和parens。这可能是对带有参数bar
和1
的双参数2
方法的调用,或者它可能是对单个参数bar
方法的调用元组值论证。解析器对bar
方法一无所知,因此它只是作为双参数方法调用进行解析。
在类型检查阶段,假设编译器确定foo
没有两个参数bar
的方法,但它确实有一个参数bar
方法,其签名是兼容元组解释。由于没有其他有效的解释,它假定这是你的意思,并将两个参数转换为元组。请注意,如果有一个带两个参数bar
方法中,即使一个是与实际参数,导电型测量仪的不会执行自动几倍转化。
答案 1 :(得分:0)
一个声明,你可以在调用on-arg函数时省略parens并不总是正确的。 请注意:
println "hello"
val puts = (s: String) => println(s)
puts "hello"
尽管这里没有元组,但也不起作用。 如果您使用中缀表示法,它可以工作。以下陈述非常有效:
Console println "hello"
val t = (1, 2)
Console println t
puts apply "hello" // puts is defined above