You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Scala wspiera mechanizm _klas case_. Klasy case są zwykłymi klasami z dodatkowymi założeniami:
14
+
Scala wspiera mechanizm _klas przypadków_. Klasy przypadków są zwykłymi klasami z dodatkowymi założeniami:
15
15
16
-
* Domyślnie immutable
16
+
* Domyślnie niemutowalne
17
17
* Można je dekomponować poprzez [dopasowanie wzorca](pattern-matching.html)
18
18
* Porównywane poprzez podobieństwo strukturalne zamiast przez referencje
19
19
* Zwięzła składnia tworzenia obiektów i operacji na nich
20
20
21
-
Poniższy przykład obrazuje hierarchię typów powiadomień, która składa się z abstrakcyjnej klasy `Notification` oraz trzech konkretnych rodzajów zaimplementowanych jako klasy case`Email`, `SMS` i `VoiceRecording`:
21
+
Poniższy przykład obrazuje hierarchię typów powiadomień, która składa się z abstrakcyjnej klasy `Notification` oraz trzech konkretnych rodzajów zaimplementowanych jako klasy przypadków`Email`, `SMS` i `VoiceRecording`:
22
22
23
23
```tut
24
24
abstract class Notification
@@ -33,17 +33,17 @@ Tworzenie obiektu jest bardzo proste: (Zwróć uwagę na to, że słowo `new` n
33
33
val emailFromJohn = Email("[email protected]", "Greetings From John!", "Hello World!")
34
34
```
35
35
36
-
Parametry konstruktora klasy case są traktowane jako publiczne wartości i można się do nich odwoływać bezpośrednio:
36
+
Parametry konstruktora klasy przypadków są traktowane jako publiczne wartości i można się do nich odwoływać bezpośrednio:
37
37
38
38
```tut
39
39
val title = emailFromJohn.title
40
40
println(title) // wypisuje "Greetings From John!"
41
41
```
42
42
43
-
W klasach case nie można modyfikować wartości pól. (Z wyjątkiem sytuacji kiedy dodasz `var` przed nazwą pola)
43
+
W klasach przypadków nie można modyfikować wartości pól. (Z wyjątkiem sytuacji kiedy dodasz `var` przed nazwą pola)
44
44
45
45
```tut:fail
46
-
emailFromJohn.title = "Goodbye From John!" // Jest to błąd kompilacji, gdyż pola klasy case są domyślnie immutable
46
+
emailFromJohn.title = "Goodbye From John!" // Jest to błąd kompilacji, gdyż pola klasy przypadku są domyślnie niezmienne
47
47
```
48
48
49
49
Zamiast tego, możesz utworzyć kopię używając metody `copy`:
println(editedEmail) // wypisuje "Email([email protected],I am learning Scala,It's so cool!)"
56
56
```
57
57
58
-
Dla każdej klasy case kompilator Scali generuje metodę `equals`, która implementuje strukturalne porównanie obiektów oraz metodę `toString`. Przykład:
58
+
Dla każdej klasy przypadku kompilator Scali wygeneruje metodę `equals`, która implementuje strukturalne porównanie obiektów oraz metodę `toString`. Przykład:
59
59
60
60
```tut
61
61
val firstSms = SMS("12345", "Hello!")
@@ -75,7 +75,7 @@ They are equal!
75
75
SMS is: SMS(12345, Hello!)
76
76
```
77
77
78
-
Jednym z najważniejszych zastosowań klas case (skąd też się wzięła ich nazwa), jest **dopasowanie wzorca**. Poniższy przykład pokazuje działanie funkcji, która zwraca różne komunikaty, w zależności od rodzaju powiadomienia:
78
+
Jednym z najważniejszych zastosowań klas przypadków (skąd też się wzięła ich nazwa), jest **dopasowanie wzorca**. Poniższy przykład pokazuje działanie funkcji, która zwraca różne komunikaty, w zależności od rodzaju powiadomienia:
Programując w Scali, zachęca się abyś jak najszerzej używał klas case do modelowania danych, jako że kod który je wykorzystuje jest bardziej ekspresywny i łatwiejszy do utrzymania:
137
+
Programując w Scali, zachęca się abyś jak najszerzej używał klas przypadków do modelowania danych, jako że kod który je wykorzystuje jest bardziej ekspresywny i łatwiejszy do utrzymania:
138
138
139
-
* Obiekty typu immutable uwalniają cię od potrzeby śledzenia zmian stanu
139
+
* Obiekty niemutowalne uwalniają cię od potrzeby śledzenia zmian stanu
140
140
* Porównanie przez wartość pozwala na porównywanie instancji tak jakby były prymitywnymi wartościami
141
141
* Dopasowanie wzorca znacząco upraszcza logikę rozgałęzień, co prowadzi do mniejszej ilości błędów i czytelniejszego kodu
W Scali, wzorce mogą być zdefiniowane niezależnie od klas case. Obiekt posiadający metodę `unapply` może funkcjonować jako tak zwany ekstraktor. Jest to szczególna metoda, która pozwala na odwrócenie zastosowania obiektu dla pewnych danych. Jego celem jest ekstrakcja danych, z których został on utworzony. Dla przykładu, poniższy kod definiuje ekstraktor dla [obiektu](singleton-objects.html)`Twice`:
14
+
W Scali, wzorce mogą być zdefiniowane niezależnie od klas przypadków. Obiekt posiadający metodę `unapply` może funkcjonować jako tak zwany ekstraktor. Jest to szczególna metoda, która pozwala na odwrócenie zastosowania obiektu dla pewnych danych. Jego celem jest ekstrakcja danych, z których został on utworzony. Dla przykładu, poniższy kod definiuje ekstraktor dla [obiektu](singleton-objects.html)`Twice`:
Copy file name to clipboardExpand all lines: pl/tutorials/tour/generic-classes.md
+1-1
Original file line number
Diff line number
Diff line change
@@ -24,7 +24,7 @@ class Stack[T] {
24
24
}
25
25
```
26
26
27
-
Klasa `Stack` modeluje zmienny stos z zawierający elementy dowolnego typu `T`. Parametr `T` narzuca ograniczenie dla metod takie, że tylko elementy typu `T` mogą zostać dodane do stosu. Podobnie metoda `top` może zwrócić tylko elementy danego typu.
27
+
Klasa `Stack` modeluje zmienny stos zawierający elementy dowolnego typu `T`. Parametr `T` narzuca ograniczenie dla metod takie, że tylko elementy typu `T` mogą zostać dodane do stosu. Podobnie metoda `top` może zwrócić tylko elementy danego typu.
Konwersja implicit z typu `S` do `T` jest określona przez wartość implicit, która jest funkcją typu `S => T` lub przez metodę implicit odpowiadającą funkcji tego typu.
14
+
Konwersja niejawna z typu `S` do `T` jest określona przez wartość domniemaną, która jest funkcją typu `S => T` lub przez metodę domniemaną odpowiadającą funkcji tego typu.
15
15
16
-
Konwersje implicit są stosowane w dwóch sytuacjach:
16
+
Konwersje niejawne mogą być są zastosowane w jednej z dwóch sytuacji:
17
17
18
18
* Jeżeli wyrażenie `e` jest typu `S` i `S` nie odpowiada wymaganemu typowi `T`.
19
19
* W przypadku wyboru `e.m` z `e` typu `T`, jeżeli `m` nie jest elementem `T`.
@@ -27,7 +27,7 @@ Poniższa operacja na dwóch listach `xs` oraz `ys` typu `List[Int]` jest dopusz
27
27
xs <= ys
28
28
```
29
29
30
-
Zakładając, że metody implicit`list2ordered` oraz `int2ordered` zdefiniowane poniżej znajdują się w danym zakresie:
30
+
Zakładając, że metody niejawne`list2ordered` oraz `int2ordered` zdefiniowane poniżej znajdują się w danym zakresie:
Domyślnie importowany obiekt `scala.Predef` deklaruje kilka predefiniowanych typów (np. `Pair`) i metod (np. `assert`) ale także wiele użytecznych konwersji implicit.
41
+
Domyślnie importowany obiekt `scala.Predef` deklaruje kilka predefiniowanych typów (np. `Pair`) i metod (np. `assert`) ale także wiele użytecznych konwersji niejawnych.
42
42
43
-
Przykładowo, kiedy wywołujemy metodę Javy, która wymaga typu `java.lang.Integer`, dopuszczalne jest przekazanie typu `scala.Int`. Dzieje się tak ponieważ `Predef`zawiera poniższe konwersje implicit:
43
+
Przykładowo, kiedy wywołujemy metodę Javy, która wymaga typu `java.lang.Integer`, dopuszczalne jest przekazanie typu `scala.Int`. Dzieje się tak ponieważ `Predef`definiuje poniższe konwersje niejawne:
Aby zdefiniować własne konwersje implicit, należy zaimportować `scala.language.implicitConversions` (albo uruchomić kompilator z opcją `-language:implicitConversions`). Ta funkcjonalność musi być włączona jawnie, ze względu na problemy jakie mogą się wiązać z ich nadmiernym stosowaniem.
52
+
Aby zdefiniować własne konwersje niejawne, należy zaimportować `scala.language.implicitConversions` (albo uruchomić kompilator z opcją `-language:implicitConversions`). Ta funkcjonalność musi być włączona jawnie, ze względu na problemy jakie mogą się wiązać z ich nadmiernym stosowaniem.
Metodę z _parametrami implicit_ można stosować tak samo jak zwyczajną metodę. W takim przypadku etykieta `implicit` nie ma żadnego znaczenia. Jednak jeżeli odpowiednie argumenty dla parametrów implicit nie zostaną jawnie określone, to kompilator dostarczy je automatycznie.
14
+
Metodę z _parametrami domniemanymi_ można stosować tak samo jak każdą zwyczajną metodę. W takim przypadku etykieta `implicit` nie ma żadnego znaczenia. Jednak jeżeli odpowiednie argumenty dla parametrów domniemanych nie zostaną jawnie określone, to kompilator dostarczy je automatycznie.
15
15
16
-
Argumenty które mogą być przekazywane jako parametry implicit można podzielić na dwie kategorie:
16
+
Argumenty które mogą być przekazywane jako parametry domniemane można podzielić na dwie kategorie:
17
17
18
-
* Najpierw dobierane są takie identyfikatory, które są dostępne bezpośrednio w punkcie wywołania metody i które określają definicję lub parametr implicit.
19
-
* W drugiej kolejności dobrane mogą być elementy modułów companion odpowiadających typom tych parametrów implicit, które są oznaczone jako `implicit`.
18
+
* Najpierw dobierane są takie identyfikatory, które są dostępne bezpośrednio w punkcie wywołania metody i które określają definicję lub parametr domniemany.
19
+
* W drugiej kolejności dobrane mogą być elementy modułów towarzyszących odpowiadających typom tych parametrów domniemanych, które są oznaczone jako `implicit`.
20
20
21
-
W poniższym przykładzie zdefiniujemy metodę `sum`, która oblicza sumę listy elementów wykorzystując operacje `add` i `unit` obiektu `Monoid`. Należy dodać, że wartości implicit nie mogą być zdefiniowane globalnie, tylko muszą być elementem pewnego modułu.
21
+
W poniższym przykładzie zdefiniujemy metodę `sum`, która oblicza sumę listy elementów wykorzystując operacje `add` i `unit` obiektu `Monoid`. Należy dodać, że wartości domniemane nie mogą być zdefiniowane globalnie, tylko muszą być elementem pewnego modułu.
22
22
23
23
```tut
24
-
/** Ten przykład wykorzystuje strukturę z algebry abstrakcyjnej aby zilustrować działanie parametrów implicit. Półgrupa jest strukturą algebraiczną na zbiorze A z łączna (która spełnia warunek: add(x, add(y, z)) == add(add(x, y), z)) operacją nazwaną add, która łączy parę obiektów A by zwrócić inny A. */
24
+
/** Ten przykład wykorzystuje strukturę z algebry abstrakcyjnej aby zilustrować działanie parametrów domniemanych. Półgrupa jest strukturą algebraiczną na zbiorze A z łączną operacją (czyli taką, która spełnia warunek: add(x, add(y, z)) == add(add(x, y), z)) nazwaną add, która łączy parę obiektów A by zwrócić inny obiekt A. */
25
25
abstract class SemiGroup[A] {
26
26
def add(x: A, y: A): A
27
27
}
@@ -30,7 +30,7 @@ abstract class Monoid[A] extends SemiGroup[A] {
30
30
def unit: A
31
31
}
32
32
object ImplicitTest extends App {
33
-
/** Aby zademonstrować jak działają parametry implicit, najpierw zdefiniujemy monoidy dla łańcuchów znaków oraz liczb całkowitych. Słowo kluczowe implicit sprawia, że oznaczone nimi wartości mogą być użyte aby zrealizować parametry implicit. */
33
+
/** Aby zademonstrować jak działają parametry domniemane, najpierw zdefiniujemy monoidy dla łańcuchów znaków oraz liczb całkowitych. Słowo kluczowe implicit sprawia, że oznaczone nimi wartości mogą być użyte aby zrealizować parametry domniemane. */
/** Metoda sum pobiera List[A] i zwraca A, który jest wynikiem zastosowania zastosowania monoidu do wszystkich kolejnych elementów listy. Oznaczając parametr m jako implicit sprawiamy, że potrzebne jest tylko podanie parametru xs podczas wywołania, ponieważ mamy już List[A], zatem wiemy jakiego typu jest w rzeczywistości A, zatem wiemy też jakiego typu Monoid[A] jest potrzebny. Możemy więc wyszukać wartość val lub obiekt w aktualnym zasięgu, który ma odpowiadający typu i użyć go bez jawnego określania referencji do niego. */
42
+
/** Metoda sum pobiera List[A] i zwraca A, który jest wynikiem zastosowania monoidu do wszystkich kolejnych elementów listy. Oznaczając parametr m jako domniemany, sprawiamy że potrzebne jest tylko podanie parametru xs podczas wywołania, ponieważ mamy już List[A], zatem wiemy jakiego typu jest w rzeczywistości A, zatem wiemy też jakiego typu Monoid[A] potrzebujemy. Możemy więc wyszukać wartość val lub obiekt w aktualnym zasięgu, który ma odpowiadający typu i użyć go bez jawnego określania referencji do niego. */
43
43
def sum[A](xs: List[A])(implicit m: Monoid[A]): A =
44
44
if (xs.isEmpty) m.unit
45
45
else m.add(xs.head, sum(xs.tail))
46
46
47
-
/** Wywołamy tutaj dwa razy sum, podając za każdym razem tylko listę. Ponieważ drugi parametr (m) jest implicit, jego wartość jest wyszukiwana przez kompilator w aktualnym zasięgu, na podstawie typu monoidu wymaganego w każdym przypadku, co oznacza że oba wyrażenia mogą być w pełni ewaluowane. */
47
+
/** Wywołamy tutaj dwa razy sum, podając za każdym razem tylko listę. Ponieważ drugi parametr (m) jest domniemany, jego wartość jest wyszukiwana przez kompilator w aktualnym zasięgu, na podstawie typu monoidu wymaganego w każdym przypadku, co oznacza że oba wyrażenia mogą być w pełni ewaluowane. */
48
48
println(sum(List(1, 2, 3))) // używa IntMonoid
49
49
println(sum(List("a", "b", "c"))) // używa StringMonoid
Copy file name to clipboardExpand all lines: pl/tutorials/tour/inner-classes.md
+1-1
Original file line number
Diff line number
Diff line change
@@ -58,7 +58,7 @@ object GraphTest extends App {
58
58
}
59
59
```
60
60
61
-
Ten kod pokazuje, że typ wierzchołka jest prefikowany przez swoją zewnętrzną instancję (która jest obiektem `g` w naszym przykładzie). Jeżeli mielibyśmy dwa grafy, system typów w Scali nie pozwoli nam na pomieszanie wierzchołków jednego z wierzchołkami drugiego, ponieważ wierzchołki innego grafu są określone innym przez inny typ.
61
+
Ten kod pokazuje, że typ wierzchołka jest prefiksowany przez swoją zewnętrzną instancję (która jest obiektem `g` w naszym przykładzie). Jeżeli mielibyśmy dwa grafy, system typów w Scali nie pozwoli nam na pomieszanie wierzchołków jednego z wierzchołkami drugiego, ponieważ wierzchołki drugiego grafu są określone przez inny typ.
Copy file name to clipboardExpand all lines: pl/tutorials/tour/lower-type-bounds.md
+1-1
Original file line number
Diff line number
Diff line change
@@ -11,7 +11,7 @@ tutorial-next: inner-classes
11
11
tutorial-previous: upper-type-bounds
12
12
---
13
13
14
-
Podczas gdy [górne ograniczenia typów](upper-type-bounds.html) zawężają typ do podtypu innego typu, *dolne ograniczenia typów* określają dany typ jako typ bazowy innego typu. Sformułowanie `T >: A` wyraża, że parametr typowy`T` lub typ abstrakcyjny `T` odwołuje się do typu bazowego `A`.
14
+
Podczas gdy [górne ograniczenia typów](upper-type-bounds.html) zawężają typ do podtypu innego typu, *dolne ograniczenia typów* określają dany typ jako typ bazowy innego typu. Sformułowanie `T >: A` wyraża, że parametr typu`T` lub typ abstrakcyjny `T` odwołuje się do typu bazowego `A`.
Copy file name to clipboardExpand all lines: pl/tutorials/tour/nested-functions.md
+1-1
Original file line number
Diff line number
Diff line change
@@ -11,7 +11,7 @@ tutorial-next: currying
11
11
tutorial-previous: higher-order-functions
12
12
---
13
13
14
-
Scala pozwala na zagnieżdżanie definicji funkcji. Poniższy obiekt określa funkcję `filter`, która dla danej listy filtruje elementy większe bądź równe niż podany próg`threshold`:
14
+
Scala pozwala na zagnieżdżanie definicji funkcji. Poniższy obiekt określa funkcję `filter`, która dla danej listy filtruje elementy większe bądź równe podanemu progowi`threshold`:
Copy file name to clipboardExpand all lines: pl/tutorials/tour/pattern-matching.md
+3-3
Original file line number
Diff line number
Diff line change
@@ -24,7 +24,7 @@ object MatchTest1 extends App {
24
24
}
25
25
```
26
26
27
-
Blok kodu z wyrażeniami `case` definiuje funkcję, która przekształca liczby całkowite do łańcuchów znaków. Słowo kluczowe `match` pozwala w wygodny sposób zastosować dopasowanie wzorca do obiektu.
27
+
Blok kodu z wyrażeniami `case` definiuje funkcję, która przekształca liczby całkowite na łańcuchy znaków. Słowo kluczowe `match` pozwala w wygodny sposób zastosować dopasowanie wzorca do obiektu.
28
28
29
29
Wzorce można także dopasowywać do różnych typów wartości:
30
30
@@ -41,5 +41,5 @@ object MatchTest2 extends App {
41
41
42
42
Pierwszy przypadek jest dopasowany, gdy `x` jest liczbą całkowitą równą `1`. Drugi określa przypadek, gdy `x` jest równe łańcuchowi znaków `"two"`. Ostatecznie mamy wzorzec dopasowania typu. Jest on spełniony gdy `x` jest dowolną liczbą całkowitą oraz gwarantuje, że `y` jest (statycznie) typu liczby całkowitej.
43
43
44
-
Dopasowanie wzorca w Scali jest najbardziej użyteczne z wykorzystaniem typów algebraicznych modelowanych przez [klasy case](case-classes.html).
45
-
Scala także pozwala też na używanie wzorców niezależnie od klas case, używając metody `unapply` definiowanej przez [obiekty ekstraktorów](extractor-objects.html).
44
+
Dopasowanie wzorca w Scali jest najbardziej użyteczne z wykorzystaniem typów algebraicznych modelowanych przez [klasy przypadków](case-classes.html).
45
+
Scala także pozwala też na używanie wzorców niezależnie od klas przypadków, używając metody `unapply` definiowanej przez [obiekty ekstraktorów](extractor-objects.html).
Wzorce ignorujące prawą stronę są użyteczne przy dekomponowaniu danych, które mogą być podtypem `Seq[A]` lub klasą case z iterowalnym parametrem, jak w poniższym przykładzie:
17
+
Wzorce ignorujące prawą stronę są użyteczne przy dekomponowaniu danych, które mogą być podtypem `Seq[A]` lub klasą przypadku z iterowalnym parametrem, jak w poniższym przykładzie:
0 commit comments