2016-01-10 1 views
6

Я изучаю Groovy и очень впечатлен тем, как он позволяет создавать интеллектуальные DSL, но меня немного путают правила, когда круглые скобки и точки являются необязательными. Рассмотрим следующий код:Groovy необязательные круглые скобки и точки

Integer take(Integer x) {x} 
take 3 plus 4 

Это работает, как ожидалось, и производит выход 7 (когда побежал в консоли), так как заводной понимает, что последняя строка в take(3).plus(4).

Теперь println take 3 plus 4 не работает, поскольку groovy понимает, что как println(take).3(plus).4, что является ерундой.

Каждый пример, который я вижу, показывает эти рода выражения сами по себе на линии, но, по-видимому

s = take 3 plus 4 

работы и сохраняет результат 7 в с. Мой вопрос: почему

println(take 3 plus 4) 

не работает? Очевидно, что groovy будет анализировать такие выражения, даже если они не являются сами по себе на линии (как показано в задании). Я бы подумал, что добавление этих круглых скобок устранит двусмысленность из формы этой строки, которая не работает, и что она будет печатать 7, как я предполагал.

Вместо groovy выдает сообщение об ошибке «неожиданный токен: 3». Насколько я могу судить, groovy не позволит вставлять скобки или точки внутри этого println, хотя это не кажется двусмысленным. Когда именно этот трюк работает?

ответ

2

Это относится к категории вызова вложенного метода, и в этом случае вы не можете опустить круглые скобки. Это вызывает неоднозначность, и результаты являются неожиданными, поскольку метод println считает, что вы передаете ему несколько параметров. Вы можете уменьшить двусмысленность, используя строгую строку в методе println.

println "${take 3 plus 4}" 

Подробнее: Omit Parentheses

+1

Это было бы решить, почему 'Println взять 3 плюс 4' не работает, но не то, почему' Println (взять 3 плюс 4) 'не делает, не должно будь то какая-либо двусмысленность (если бы это интерпретировалось как несколько параметров, между ними была бы запятая, поэтому groovy должен был бы определить, что это не значит). Кроме того, эта ссылка говорит, что она не должна работать в назначении (хотя пример кода показывает ее работу), но это так. Интересно, немного ли это сейчас. Гид языка не настолько строгий и предполагает, что он должен работать, когда он завернут как последняя форма. – Matthew

+0

+1 для того, чтобы показать мне, как я могу заставить это работать в println, но я не уверен, полностью ли это отвечает на мой вопрос. – Matthew

+0

Это неоднозначно, потому что метод println не знает, для оценки кода ** возьмите 3 плюс 4 ** _to_ ** take (3) .plus (4) ** до выполнения его операции над ним. Все, что находится справа от знака '=', является выражением и оценивается перед назначением переменной. $ {} Говорят сначала оценить этот код, а затем называть println. – dspano