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ędna
Podobnie 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
casei 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