为什么此 Scala 表达式中的无效函数需要括号?

发布于 2024-09-09 06:41:32 字数 529 浏览 6 评论 0原文

对我来说,这无法使用 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 进行编译。对我来说最终的:

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

为什么我需要在这里执行 getChannel() 而不是仅仅 getChannel

This doesn't compile with Scala 2.7.7.final or 2.8.0.final for me:

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

This does compile with Scala 2.7.7.final and 2.8.0.final for me:

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

Why is it that I need to do getChannel() instead of just getChannel here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

勿挽旧人 2024-09-16 06:41:32

一般规则是编译器像您的情况一样解释字符串

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

The general rule is that the compiler interprets strings like

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

as

object method parameter method parameter method parameter

so in your case, that means

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

so the compiler tries to call transferTo as a free function so it can pass its result as a parameter to getChannel. When you add the parentheses, you get

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

new FileInputStream("test.txt")    // object
getChannel                         // method
()                                 // parameter (empty parameter list)
transferTo                         // method
(...)                              // parameter
硪扪都還晓 2024-09-16 06:41:32

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

 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("测试复制.txt") getChannel
  • e = 0
  • f = Long.MaxValue

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

The reason is really simple. If you are using spaces instead of .'s to chain method calls then:

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

In your case the last two parameters are being called like (because d is more than one parameter, d, e and f say):

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

i.e. the same as the first case. However, you want the call to be:

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

Which is not the same!

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

This has not changed between 2.7 and 2.8 as far as I'm aware!

半夏半凉 2024-09-16 06:41:32

我相信是因为编译器不清楚如何划分标记。是 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)

I believe because it's not clear to the compiler how to divide the tokens up. Is it new FileInputStream("test.txt")(getChannel, transferTo(...))? new (FileInputStream("test.txt"), getChannel, transferTo(...))? (new FileInputStream("test.txt")).getChannel(transferTo(...))? The compiler doesn't have enough information to know that transferTo is a property of the object returned by getChannel.

For maximum clarity you'd have something like:

(new FileInputStream("test.txt")).getChannel().transferTo(
  (new FileOutputStream("test-copy.txt")).getChannel(), 0, Long.MaxValue)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文