Scala为什么以及如何在调用一个arg函数时特别处理元组?

Dun*_*gor 13 scala tuples

scala将多个函数调用参数合并到一个元组中 - 这可以被禁用吗?讨论Scala创建一个绑定到一个arg函数的元组.这导致了

scala> println(1, 2)
(1,2)
Run Code Online (Sandbox Code Playgroud)

答案说编译器允许在没有parens的情况下调用一个arg函数,因此逻辑上这是对带有元组的println的调用.

但是不能使用单个元组参数调用println

scala> 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
           ^
Run Code Online (Sandbox Code Playgroud)

所以其他事情正在发生.为什么元组在这里特别?

Aar*_*rup 15

此解释相反,Scala 解析 println(1,2)(或Console println (1,2)就此而言)解析任何双参数方法调用的方式相同.稍后,编译器通过将方法参数包装在元组中来匹配实际的方法类型签名来转换调用.

如果编译器没有这样做,那么完全有效的表达式Console println (1,2)将无法编译,因为println它不会采用多个参数.此行为还有其他有效用例.

foo bar (1,2)从编译器的角度考虑一个表达式,记住Scala有特殊的语法,允许你删除.方法调用上的parens.这可能是一个两个参数调用bar带参数的方法12,或者它可能是带有一个参数调用bar带有一个元组值参数的方法.解析器对该bar方法一无所知,因此它只是作为双参数方法调用进行解析.

在类型检查阶段,假设编译器确定foo没有双参数bar方法,但它确实有一个单参数bar方法,其签名与元组解释兼容.由于没有其他有效的解释,它假定这是你的意思,并将两个参数转换为元组.请注意,如果存在双参数bar方法,即使是与实际参数不兼容的方法,则typer 也不会执行自动元组转换.