为什么我在这个Scala表达式中需要这个nullary函数的括号?

时间:2010-07-14 15:38:01

标签: scala syntax dsl

对于我来说,这个无法编译 Scala 2.7.7.final或2.8.0.final:

new FileInputStream("test.txt") getChannel transferTo(
    0, Long.MaxValue, new FileOutputStream("test-copy.txt") getChannel)

对于我来说,使用Scala 2.7.7.final和2.8.0.final编译

new FileInputStream("test.txt") getChannel() transferTo(
    0, Long.MaxValue, new FileOutputStream("test-copy.txt") getChannel)

为什么我需要getChannel()而不仅仅是getChannel

3 个答案:

答案 0 :(得分:6)

一般规则是编译器解释像

这样的字符串
new FileInputStream("test.txt") getChannel transferTo(...)

作为

object method parameter method parameter method parameter

所以在你的情况下,这意味着

new FileInputStream("test.txt")    // object
getChannel                         // method
transferTo(...)                    // parameter

所以编译器尝试将transferTo作为自由函数调用,以便它可以将其结果作为参数传递给getChannel。当你添加括号时,你得到

new FileInputStream("test.txt") getChannel() transferTo(...)

new FileInputStream("test.txt")    // object
getChannel                         // method
()                                 // parameter (empty parameter list)
transferTo                         // method
(...)                              // parameter

答案 1 :(得分:3)

原因很简单。如果您使用空格而不是。来链接方法调用,那么:

 a b c d     //is parsed as a call to
 (a.b(c))(d)

在你的情况下,最后两个参数被调用(因为d是多个参数,def说:

a b c(d, e, f)    //is parsed as a call to
a.b(c(d, e, f))

即。与第一种情况相同。但是,您希望呼叫为:

(a b).c(d, e, f)

哪个不一样!

  • a = new FileInputStream("test.txt")
  • b = getChannel
  • c = transferTo
  • d = new FileOutputStream("test-copy.txt") getChannel
  • e = 0
  • f = Long.MaxValue

据我所知,这在2.7和2.8之间没有变化!

答案 2 :(得分:0)

我相信因为编译器不清楚如何划分令牌。是new FileInputStream("test.txt")(getChannel, transferTo(...))吗? new (FileInputStream("test.txt"), getChannel, transferTo(...))(new FileInputStream("test.txt")).getChannel(transferTo(...))?编译器没有足够的信息知道transferTogetChannel返回的对象的属性。

为了获得最大的清晰度,您可以使用以下内容:

(new FileInputStream("test.txt")).getChannel().transferTo(
  (new FileOutputStream("test-copy.txt")).getChannel(), 0, Long.MaxValue)