2012-08-10 5 views
10

Я начинаю практиковать в Scala, и я видел несколько разных синтаксисов для вызова метода. Некоторые из них хороши, как игнорирования скобки для метода без параметров, или игнорируя точку как вScala - синтаксис вызова метода

1 to 10 

, но некоторые действительно озадачить меня. например:

breakable { ... } 

это просто вызов метода? Могу ли я также сделать это для нескольких параметров или параметра, который не является параметром без параметров?

Благодаря

+2

Да, это закрытие. вы передаете блок кода в метод. Обратите внимание, что в Scala вы можете использовать {} вместо() для передачи одного параметра методам – aishwarya

+0

Что вас беспокоит? Это блок кода ('{...}') после имени метода или тот факт, что мы не префикс метода с именем объекта/класса? – Nicolas

ответ

22

Есть два стандартных способа методов призывающих:

obj.method(params) // dot notation 
obj method (params) // operator notation 

выше может быть изменено следующими способами:

  1. Если params является единственным параметром, вы можете заменить () на {}.
  2. Если params - это единственный параметр и, вы используете служебную запись, вы можете удалить скобки.
  3. Если method не принимает параметры, вы можете отказаться от (params) (то есть опустить пустой ()).
  4. Если method заканчивается :, то он фактически привязывается к в операторской нотации. То есть (params) method_: obj эквивалентен obj.method_:(params).
  5. В любом случае, пробелы необязательны, если идентификаторы могут быть указаны отдельно. Таким образом, можно добавить пробелы к точечной нотации, например obj . method (params), или написать .method(params) на следующей строке - как это часто бывает с цепочкой вызовов, - а также удалить пробелы из операторской нотации, как в a+b.

Есть также некоторые вещи с кортежем, но я стараюсь избегать этого, поэтому я не уверен в точном правиле.

Ничего из этого не объяснит пример, с которым вы смущены.Перед тем, как объяснить это, однако, я хотел бы показать некоторые синтаксический сахар, которые также могут быть использованы для вызова методов:

obj(params) // equivalent to obj.apply(params) 
obj.x = y // equivalent to obj.x_=(y), if obj.x also exists 
obj(x) = y // equivalent to obj.update(x, y) 
obj op= y // equivalent to obj = obj op y, if op is symbolic 
~obj  // equivalent to obj.unary_~; also for !, + and -, but no other symbol 

Хорошо, теперь к примеру, вы дали. Можно указать импорт членов стабильных значений. Java может сделать это для статических методов со своим статическим импортом, но Scala имеет более общий механизм: импорт из пакетов, объектов или общих экземпляров ничем не отличается: он включает как членов типа, так и членов значения. Методы относятся к последней категории.

Итак, представьте, что у вас есть val a = 2, и вы делаете import a._. Это позволит охватить все методы Int, поэтому вы можете напрямую их вызвать. Вы не можете сделать +(2), потому что будет истолковано как призыв к unary_+, но вы могли бы назвать *(4), например:

scala> val a = 2 
a: Int = 2 

scala> import a._ 
import a._ 

scala> *(4) 
res16: Int = 8 

Теперь, вот правило. Вы можете позвонить

method(params) 

Если:

  1. method был импортирован в область видимости.
  2. Вы держите скобки (даже если есть только один параметр)

Обратите внимание, что есть проблема старшинства, а также. Если вы напишете obj method(params), Scala предположим, что method относится к obj, даже если он был импортирован в область.

+0

Отличный ответ. Я просто задал вопрос о вашей точке номер 1, о возможности вызова метода с помощью {} нотации вместо(). Есть ли какая-либо конкретная причина, по которой этот синтаксис доступен? Этот синтаксис, по-видимому, широко используется во многих рамках и их документальных примерах. Мне интересно, поддерживается ли этот конкретный синтаксис по очень конкретной, функциональной причине. Обычно ли он используется при передаче замыканий в качестве аргументов функции? Я хотел бы понять его корни, чтобы я мог понять и объяснить это с ясностью. Благодарю. – HiChews123

+2

@ acspd7 Ну, '()' и '{}' имеют разные значения внутри _expression_. То есть '2 * (3 + 4)' и '2 * {3 + 4}' имеют одинаковый результат, но это разные вещи. Вы можете только выражать выражения в круглой скобке, тогда как вы добавляете _definitions_ и _statements_ внутри фигурных скобок, а значение последнего оператора - это значение выражения (фигурные скобки - это сами, выражение). Причина, по которой 'f (...)' может быть заменена на 'f {...}', - это просто так, что людям не нужно писать 'f ({...})'. Это позволяет людям писать «пользовательские» структуры управления, которые выглядят как родные. –

15

Если desugar это мы будем иметь:

breakable({ ... }) 

это соответствует подписи

breakable: (op: ⇒ Unit): Unit 

и использует так назвал вызов по имени аргументов (вы можете думать, из этого как передать блок кода в качестве аргумента)

Более Скале позволяет написать следующее:

scala> def foo (op1: => Unit)(op2: => Unit) = {op1;op2;} 
foo: (op1: => Unit)(op2: => Unit)Unit 

scala> foo { println(1) } { println(2) } 
1 
2 

Выше приведен пример кэрри функции

Смежные вопросы