Scala 在调用单参数函数时为什么以及如何特殊对待元组?
scala 将多个函数调用参数合并到一个元组中 - 可以禁用此功能吗? 讨论了 Scala 创建一个元组以绑定到一个 arg 函数。这导致
scala> println(1, 2)
(1,2)
答案说编译器允许在没有括号的情况下调用一个 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
^
因此会发生其他情况。为什么元组在这里很特别?
scala coalesces multiple function call parameters into a Tuple -- can this be disabled? discusses Scala creating a tuple to bind to one arg function. This results in
scala> println(1, 2)
(1,2)
The answer says that the compiler allows one arg functions to be called with no parens, so that logically this is a call to println with a tuple.
But println cannot be called with a single tuple parameter
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
^
so something else is going on. Why are tuples special here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
与相反这个解释,Scala解析
println(1,2)
(或Console println (1,2)
)它以同样的方式解析任何双参数方法调用。随后,编译器通过将方法参数包装在元组中来转换调用,以匹配实际的方法类型签名。如果编译器不这样做,像
Console println (1,2)
这样完全有效的表达式将无法编译,因为println
不接受多个参数。此行为还有其他有效用例。从编译器的角度考虑像
foo bar (1,2)
这样的表达式,请记住 Scala 有特殊的语法,允许您删除.
和括号在方法调用上。这可能是对带有参数1
和2
的双参数bar
方法的调用,也可能是对单参数的调用带有单个元组值参数的bar
方法。解析器对bar
方法一无所知,因此它只是解析为两个参数的方法调用。在类型检查阶段,假设编译器确定
foo
没有双参数bar
方法,但有一个单参数bar
其签名与元组解释兼容的方法。由于没有其他有效的解释,它假设这就是您的意思并将两个参数转换为一个元组。请注意,如果存在两个参数的bar
方法,即使该方法与实际参数不兼容,打字器也不会执行自动元组转换。Contrary to this explanation, Scala parses
println(1,2)
(orConsole println (1,2)
for that matter) the same way it parses any two-argument method call. Later, the compiler transforms the call by wrapping the method arguments in a tuple to match the actual method type signature.If the compiler did not do this, perfectly valid expressions like
Console println (1,2)
would fail to compile becauseprintln
does not take multiple arguments. There are also other valid use cases for this behavior.Consider an expression like
foo bar (1,2)
from the compiler's point of view, keeping in mind that Scala has special syntax that allows you to drop the.
and the parens on method calls. This could be a call to a two-argumentbar
method with arguments1
and2
, or it could be a call to a one-argumentbar
method with a single tuple-valued argument. The parser doesn't know anything about thebar
method, so it just parses as a two-argument method call.During the type checking phase, suppose the compiler determines that
foo
has no two-argumentbar
method but that it does have a one-argumentbar
method whose signature is compatible with the tuple interpretation. Since there is no other valid interpretation, it assumes that this is what you meant and transforms the two arguments into a tuple. Note that if there is a two-argumentbar
method, even one that is incompatible with the actual arguments, the typer will not perform the auto-tupling transformation.调用 on-arg 函数时可以省略括号的说法并不总是正确的。
请注意:
尽管这里没有元组,但也不起作用。
如果您使用中缀表示法,它会起作用。以下语句效果很好:
A statement, that you can omit parens when calling on-arg function is not always true.
Note, that:
don't work either, despite that there's no tuple here.
It works if you use infix notation. Following statements work great: