Зачем мне скобки для этой нулевой функции в этом выражении Scala? - PullRequest
3 голосов
/ 14 июля 2010

не компилируется с 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 ]

6 голосов
/ 15 июля 2010

Общее правило состоит в том, что компилятор интерпретирует строки как

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
3 голосов
/ 15 июля 2010

Причина действительно проста. Если вы используете пробелы вместо. Для цепочки вызовов методов, то:

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

В вашем случае последние два параметра вызываются как (потому что d это более одного параметра, d, e и f скажем):

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!

0 голосов
/ 14 июля 2010

Я верю, потому что компилятору не ясно, как разделить токены.Это new FileInputStream("test.txt")(getChannel, transferTo(...))?new (FileInputStream("test.txt"), getChannel, transferTo(...))?(new FileInputStream("test.txt")).getChannel(transferTo(...))?Компилятору не хватает информации, чтобы знать, что transferTo является свойством объекта, возвращаемого getChannel.

Для максимальной ясности у вас будет что-то вроде:

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