Próbowałem kiedyś o tym napisać, ale ostatecznie zrezygnowałem, ponieważ zasady są nieco rozproszone. Zasadniczo musisz się z tym pogodzić.
Być może najlepiej skoncentrować się na tym, gdzie nawiasy klamrowe i nawiasy mogą być używane zamiennie: podczas przekazywania parametrów do wywołań metod. Ty może zastąpić nawias z klamrami, wtedy i tylko wtedy, gdy metoda oczekuje jednego parametru. Na przykład:
List(1, 2, 3).reduceLeft{_ + _} // valid, single Function2[Int,Int] parameter
List{1, 2, 3}.reduceLeft(_ + _) // invalid, A* vararg parameter
Jednak musisz wiedzieć więcej, aby lepiej zrozumieć te zasady.
Zwiększone sprawdzanie kompilacji za pomocą parens
Autorzy Spray zalecają okrągłe pareny, ponieważ dają zwiększone sprawdzanie kompilacji. Jest to szczególnie ważne w przypadku DSL, takich jak spray. Za pomocą parens informujesz kompilator, że powinien mieć tylko jedną linię; dlatego jeśli przypadkowo podasz dwa lub więcej, będzie narzekać. Teraz nie jest tak w przypadku nawiasów klamrowych - jeśli na przykład zapomnisz gdzieś operatora, kod się skompiluje, a otrzymasz nieoczekiwane wyniki i potencjalnie bardzo trudny do znalezienia błąd. Poniżej wymyślono (ponieważ wyrażenia są czyste i przynajmniej dają ostrzeżenie), ale wskazuje na to:
method {
1 +
2
3
}
method(
1 +
2
3
)
Pierwsza kompiluje, druga daje error: ')' expected but integer literal found
. Autor chciał pisać 1 + 2 + 3
.
Można argumentować, że podobnie jest w przypadku metod wieloparametrowych z domyślnymi argumentami; nie można przypadkowo zapomnieć przecinka, aby oddzielić parametry podczas korzystania z parens.
Gadatliwość
Ważna często pomijana uwaga na temat gadatliwości. Używanie nawiasów klamrowych nieuchronnie prowadzi do pełnego kodu, ponieważ przewodnik po stylu Scala wyraźnie stwierdza, że zamykanie nawiasów klamrowych musi odbywać się w ich własnej linii:
… Nawias zamykający znajduje się w swoim własnym wierszu bezpośrednio po ostatnim wierszu funkcji.
Wiele auto-reformaterów, takich jak IntelliJ, automatycznie wykona to ponowne formatowanie. Staraj się więc trzymać okrągłe pareny, kiedy możesz.
Notacja Infix
Gdy używasz notacji infix, List(1,2,3) indexOf (2)
możesz pominąć nawias, jeśli jest tylko jeden parametr i zapisać go jako List(1, 2, 3) indexOf 2
. Nie dotyczy to notacji kropkowej.
Zauważ też, że jeśli masz pojedynczy parametr, który jest wyrażeniem wieloznacznym, takim jak x + 2
lub a => a % 2 == 0
, musisz użyć nawiasu, aby wskazać granice wyrażenia.
Krotki
Ponieważ czasami można pominąć nawias, czasami krotka wymaga dodatkowego nawiasu, np. W ((1, 2))
, a czasami nawias zewnętrzny można pominąć, jak w (1, 2)
. Może to powodować zamieszanie.
Literały funkcji / funkcji częściowych za pomocą case
Scala ma składnię dla literałów funkcji i częściowych funkcji. To wygląda tak:
{
case pattern if guard => statements
case pattern => statements
}
Jedynymi innymi miejscami, w których można używać case
instrukcji, są słowa kluczowe match
i catch
:
object match {
case pattern if guard => statements
case pattern => statements
}
try {
block
} catch {
case pattern if guard => statements
case pattern => statements
} finally {
block
}
Nie można używać case
instrukcji w żadnym innym kontekście . Tak więc, jeśli chcesz użyć case
, potrzebujesz nawiasów klamrowych. Jeśli zastanawiasz się, co sprawia, że różnica między funkcją a funkcją częściową jest dosłowna, odpowiedź brzmi: kontekst. Jeśli Scala spodziewa się funkcji, otrzymasz ją. Jeśli oczekuje funkcji częściowej, otrzymujesz funkcję częściową. Jeśli spodziewane są oba, pojawia się błąd dotyczący niejednoznaczności.
Wyrażenia i bloki
Nawiasów można użyć do wykonania podwyrażeń. Nawiasów klamrowych można używać do tworzenia bloków kodu ( nie jest to dosłowna funkcja, więc wystrzegaj się próbowania używania go jak jednego). Blok kodu składa się z wielu instrukcji, z których każda może być instrukcją importu, deklaracją lub wyrażeniem. To wygląda tak:
{
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 )
Tak więc, jeśli potrzebujesz deklaracji, wielu instrukcji, import
lub czegoś podobnego, potrzebujesz nawiasów klamrowych. Ponieważ wyrażenie jest stwierdzeniem, nawiasy klamrowe mogą pojawiać się w nawiasach. Ale ciekawe jest to, że bloki kodu są również wyrażenia, więc można z nich korzystać w dowolnym miejscu wewnątrz wyrażenia:
( { var x = 0; while (x < 10) { x += 1}; x } % 5) + 1
Ponieważ wyrażenia są wyrażeniami, a bloki kodów są wyrażeniami, wszystko poniżej jest poprawne:
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...
Gdzie nie są wymienne
Zasadniczo, nie można zastąpić {}
z ()
lub odwrotnie nigdzie indziej. Na przykład:
while (x < 10) { x += 1 }
To nie jest wywołanie metody, więc nie możesz napisać go w żaden inny sposób. Cóż, można umieścić nawiasy klamrowe wewnątrz nawiasów dla osób condition
, jak również wykorzystania nawiasie wewnątrz nawiasy dla bloku kodu:
while ({x < 10}) { (x += 1) }
Mam nadzieję, że to pomoże.