Я однажды пытался написать об этом, но в конце концов сдался, так как правила несколько размыты.По сути, вам придется освоить его.
Возможно, лучше сконцентрироваться на взаимозаменяемом использовании фигурных скобок и скобок: при передаче параметров в вызовы методов.Вы можете заменить круглые скобки фигурными скобками, если и только если метод ожидает один параметр.Например:
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 четко указано, что закрывающие фигурные скобки должны быть на отдельной строке:
… закрывающая фигурная скобка находится на собственной строкесразу после последней строки функции.
Многие автоформаты, как в IntelliJ, автоматически выполнят это переформатирование для вас.Поэтому старайтесь использовать круглые скобки, когда можете.
Нотация Infix
При использовании инфиксной нотации, например 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) }
Итак, я надеюсь, что это поможет.