W tym artykule przyjrzę się niektórym podstawowym cechom języka Scala w odniesieniu do innych znanych mi języków. Będzie tu mowa o deklaracjach i operatorach.
Deklarowanie zmiennych i wartości
Deklaracja zmiennej wyrażana jest za pomocą słowa kluczowego var
, nazwy zmiennej, opcjonalnego typu i obowiązkowej wartości początkowej.
var x = 1.0 // typ zmiennej 'Double' wywiedziony // z wartości początkowej var x1: Any = 1.0 // jawna deklaracja typu czasem jest niezbędnaPodobnie ma się sprawa z wartością (ang. value), jednak są dwie różnice: pierwsza to oczywiście inne słowo kluczowe, druga to brak możliwości zmiany wartości po zainicjowaniu. Jest to odpowiednik javowej zmiennej oznaczonej słowem kluczowym
final
lub const
w C++.
val greet = "Hello" // typ wartości 'String' wywiedziony // z wartości początkowej val greet: String = null // to samo co powyżej, ale z jawną deklaracją typu, // który nie wynika z przypisanej wartości
Podobnie jak Java, Scala posiada siedem podstawowych typów numerycznych: Byte
, Char
, Short
, Int
, Long
, Float
, Double
i Boolean
. Jednak odwrotnie niż w Javie (czy C++) typy te są klasami. Z tego powodu zupełnie legalnie można wywoływać metody powyższych klas, jak w przykładzie poniżej:
1.toString() // zwraca łańcuch "1" 1.to(10) // zwraca zakres typu Range(1,2,3,4,5,6,7,8,9,10)
Uwaga na ENTER
Średniki na końcu deklaracji nie są obowiązkowe, chyba że w tej samej linii miałoby się znaleźć ich więcej. Zalecane jest, aby kończyć deklarację znakiem końca linii. Znak ten (dalej będę używał skrótu nl) jest w Scali traktowany jako specjalny jeśli są spełnione następujące warunki:
- Ciąg znaków bezpośrednio poprzedzający nl może zakończyć deklarację, czyli dowolny literał, identyfikator lub jedno z następujących słów kluczowych lub znaków:
this null true false return type <xml-start> _ ) ] }
- Ciąg znaków bezpośrednio następujący po nl może rozpocząć deklarację, czyli dowolny ciąg znaków poza następującymi:
catch else extends finally forSome match with yield , . ; : = => <- <: <% >: # [ ) ] }
- Znak nl znajduje się w regionie gdzie jest to dozwolone, czyli wszędzie poza obszarami:
- pomiędzy
(
i)
oraz[
i]
, chyba że wewnątrz zagnieżdżono obszar w którym nl jest dozwolony. - pomiędzy
case
i odpowiadającym mu symbolem=>
, chyba że wewnątrz zagnieżdżono obszar dozwolony dla nl - analizowanymi w trybie XML
- pomiędzy
Nie zawsze jednak znak nowej linii oznacza koniec deklaracji. Ma to miejsce w następujących przykładach, zaczerpniętych z draftu specyfikacji języka Scala, w przypadku znaków nl pomiędzy liniami 1-2, 4-5, 7-8 oraz 10-11:
if (x > 0) x = x - 1 while (x > 0) x = x / 2 for (x <- 1 to 10) println(x) type IntList = List[Int]
Natomiast należy bardzo uważać na nadmiarowe znaki nowego wiersza, ponieważ w niektórych przypadkach mogą one całkowicie zmienić sposób działania kodu. Poniższy przykład definiuje anonimową klasę:
new Iterator[Int] { private var x = 0 def hasNext = true def next = { x += 1; x } }Podczas, gdy dodanie dodatkowego wiersza:
new Iterator[Int] { private var x = 0 def hasNext = true def next = { x += 1; x } }powoduje zinterpretowanie powyższego kodu, jako utworzenie obiektu z następującym po nim lokalnym blokiem.
Kolejny przykład opisuje pojedyncze wyrażenie:
x < 0 || x > 10Podczas, gdy dodatkowy wiersz tworzy z powyższego kodu dwa wyrażenia:
x < 0 || x > 10
Operatory
Większość operatorów znanych w Javie czy C++ występuje również w Scali. Jednak nie ma tu operatorów ++
oraz --
. Zamiast tego należy używać x+=1
i x-=1
.
Ponieważ istnieje możliwość przeciążania operatorów (nieobecna w Jave, ale możliwa w C++), można sobie uzupełnić braki. Twórcy języka uznali jednak, że nie ma potrzeby tworzenia dodatkowej reguły parsera po to tylko, by zaoszczędzić programistom jednego uderzenia klawisza.
Operatory w Scali są właściwie metodami, to znaczy poniższe wywołanie:
1 + 2można zastąpić:
1.+(2)Scala pozwala na definiowanie nazw metod składających się nie tylko ze znaków alfanumerycznych. Dlatego np. klasa
BigInt
zawiera metodę (operator) /%
, która zwraca parę liczb oznaczających wyniku dzielenia całkowitego oraz resztę z tego dzielenia.
Generalnie można zapisywać:
a metoda bjako skrót zapisu:
a.metoda(b)Dzięki temu każda metoda może pełnić rolę operatora, a wspomniany już wyżej przykład:
1.to(10)można zapisać nieco ładniej:
1 to 10uzyskując ten sam efekt.
W kolejnym artykule zajmę się deklaracjami funkcji i metod, ich wywoływaniem oraz magią metody apply
.
Brak komentarzy:
Prześlij komentarz