Я попробовал раз писать об этом, но в конце концов я сдался, так как правила несколько размыты. В принципе, вам придется повесить его.
Возможно, лучше сосредоточиться на том, где фигурные скобки и скобки могут использоваться взаимозаменяемо: при передаче параметров вызовам метода. Вы можете заменить скобку фигурными скобками, если и только если метод ожидает единственный параметр. Например:
List(1, 2, 3).reduceLeft{_ + _} // valid, single Function2[Int,Int] parameter
List{1, 2, 3}.reduceLeft(_ + _) // invalid, A* vararg parameter
Тем не менее, вам нужно больше знать, чтобы лучше понять эти правила.
Авторы Spray рекомендуйте круглые парсеры, потому что они дают повышенную проверку компиляции. Это особенно важно для DSL, таких как Spray. Используя parens, вы сообщаете компилятору, что ему должна быть предоставлена только одна строка; поэтому, если вы случайно дадите ему два или более, он будет жаловаться. Теперь это не так с фигурными фигурными скобками - если, например, вы где-то забыли оператор, тогда ваш код будет компилироваться, и вы получите неожиданные результаты и потенциально очень сложную ошибку. Ниже изобретено (так как выражения чисты и, по крайней мере, дают предупреждение), но делает точку:
method {
1 +
2
3
}
method(
1 +
2
3
)
Первые компиляции, вторая дает error: ')' expected but integer literal found
. Автор хотел написать 1 + 2 + 3
.
Можно утверждать, что это похоже на многопараметрические методы с аргументами по умолчанию; невозможно случайно забыть запятую, чтобы отделять параметры при использовании парнеров.
Важное часто забытое примечание о многословии. Использование фигурных скобок неизбежно приводит к подробному коду, поскольку руководство стиля Scala четко заявляет, что закрытие фигурных скобок должно быть в их собственной строке:
... закрывающая фигурная скобка находится на ее собственной строки сразу после последней строки функции.
blockquote>Многие автореформаторы, как и в IntelliJ, автоматически выполнит эту переформатировку для вас. Так что старайтесь использовать круглые паренны, когда сможете.
Инфиксная нотация
При использовании инфиксной нотации, например
List(1,2,3) indexOf (2)
, вы можете опустить скобки, если есть только один параметр и записать его какList(1, 2, 3) indexOf 2
. Это не относится к точечной нотации.Обратите также внимание, что если у вас есть один параметр, который является выражением с несколькими токенами, например
x + 2
илиa => a % 2 == 0
, вы должны использовать скобки для указания границы выражения.Кортежи
Поскольку вы иногда можете опускать скобки, иногда кортеж нуждается в дополнительных скобках, например, в
((1, 2))
, а иногда внешняя скобка может быть опущена, например в(1, 2)
. Это может вызвать путаницу.Функциональные / частичные литералы функции с
case
Scala имеет синтаксис для литералов функций и частичных функций. Это выглядит так:
{ case pattern if guard => statements case pattern => statements }
Единственными другими местами, где вы можете использовать
case
заявления, являются ключевые словаmatch
иcatch
:object match { case pattern if guard => statements case pattern => statements }
try { block } catch { case pattern if guard => statements case pattern => statements } finally { block }
Вы не можете использовать выражения
case
в любом другом контексте . Итак, если вы хотите использоватьcase
, вам нужны фигурные скобки . В случае, если вам интересно, что делает различие между функцией и литералом частичной функции, ответ таков: контекст. Если Scala ожидает функцию, вы получите функцию. Если он ожидает частичную функцию, вы получаете частичную функцию. Если оба они ожидаются, это дает ошибку в двусмысленности.Выражения и блоки
Скобки могут использоваться для создания подвыражений. Кудрявые фигурные скобки можно использовать для создания блоков кода (это не литер функций, поэтому не стоит пытаться использовать его как один). Блок кода состоит из нескольких операторов, каждый из которых может быть оператором импорта, объявлением или выражением. Это происходит следующим образом:
{ import stuff._ statement ; // ; optional at the end of the line statement ; statement // not optional here var x = 0 // declaration while (x < 10) { x += 1 } // stuff (x % 5) + 1 // expression } ( expression )
Итак, если вам нужны декларации, несколько операторов,
import
или что-то в этом роде, вам нужны фигурные скобки. И поскольку выражение является выражением, скобки могут появляться внутри фигурных скобок. Но интересно то, что блоками кода являются выражения также , поэтому вы можете использовать их где угодно внутри выражение:( { var x = 0; while (x < 10) { x += 1}; x } % 5) + 1
Итак, поскольку выражения - это выражения, а блоки кодов - выражения, все ниже:
1 // literal (1) // expression {1} // block of code ({1}) // expression with a block of code {(1)} // block of code with an expression ({(1)}) // you get the drift...
Где они не взаимозаменяемы
В принципе, вы не можете заменить
{}
на()
или наоборот в другом месте. Например:while (x < 10) { x += 1 }
Это не вызов метода, поэтому вы не можете записать его каким-либо другим способом. Ну, вы можете поместить фигурные скобки внутри в скобки для
condition
, а также использовать скобки внутри фигурные скобки для блока кода:while ({x < 10}) { (x += 1) }
Итак, я надеюсь, что это поможет.