Skip to content

Commit a018c28

Browse files
authored
Merge pull request #652 from adamwy/master
Polish translation of the Scala tutorial
2 parents 336411e + 1ec6c96 commit a018c28

33 files changed

+2020
-0
lines changed

Diff for: pl/tutorials/tour/abstract-types.md

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
---
2+
layout: tutorial
3+
title: Typy abstrakcyjne
4+
5+
disqus: true
6+
7+
tutorial: scala-tour
8+
num: 22
9+
languages: [ba, es, ko, pl]
10+
language: pl
11+
tutorial-next: compound-types
12+
tutorial-previous: inner-classes
13+
---
14+
15+
W Scali, klasy są parametryzowane wartościami (parametry konstruktora) oraz typami (jeżeli klasa jest [generyczna](generic-classes.html)). Aby zachować regularność, zarówno typy jak i wartości są elementami klasy. Analogicznie mogą one być konkretne albo abstrakcyjne.
16+
17+
Poniższy przykład definiuje wartość określaną przez abstrakcyjny typ będący elementem [cechy](traits.html) `Buffer`:
18+
19+
```tut
20+
trait Buffer {
21+
type T
22+
val element: T
23+
}
24+
```
25+
26+
*Typy abstrakcyjne* są typami, które nie są jednoznacznie określone. W powyższym przykładzie wiemy tylko, że każdy obiekt klasy `Buffer` posiada typ `T`, ale definicja klasy `Buffer` nie zdradza jakiemu konkretnie typowi on odpowiada. Tak jak definicje wartości, możemy także nadpisać definicje typów w klasach pochodnych. Pozwala to nam na odkrywanie dodatkowych informacji o abstrakcyjnym typie poprzez zawężanie jego ograniczeń (które opisują możliwe warianty konkretnego typu).
27+
28+
W poniższym programie definiujemy klasę `SeqBuffer`, która ogranicza możliwe typy `T` do pochodnych sekwencji `Seq[U]` dla nowego typu `U`:
29+
30+
```tut
31+
abstract class SeqBuffer extends Buffer {
32+
type U
33+
type T <: Seq[U]
34+
def length = element.length
35+
}
36+
```
37+
38+
Cechy oraz [klasy](classes.html) z abstrakcyjnymi typami są często używane w połączeniu z anonimowymi klasami. Aby to zilustrować wykorzystamy program, w którym utworzymy bufor sekwencji ograniczony do listy liczb całkowitych:
39+
40+
```tut
41+
abstract class IntSeqBuffer extends SeqBuffer {
42+
type U = Int
43+
}
44+
45+
object AbstractTypeTest1 extends App {
46+
def newIntSeqBuf(elem1: Int, elem2: Int): IntSeqBuffer =
47+
new IntSeqBuffer {
48+
type T = List[U]
49+
val element = List(elem1, elem2)
50+
}
51+
val buf = newIntSeqBuf(7, 8)
52+
println("length = " + buf.length)
53+
println("content = " + buf.element)
54+
}
55+
```
56+
57+
Typ zwracany przez metodę `newIntSeqBuf` nawiązuje do specjalizacji cechy `Buffer`, w której typ `U` jest równy `Int`. Podobnie w anonimowej klasie tworzonej w metodzie `newIntSeqBuf` określamy `T` jako `List[Int]`.
58+
59+
Warto zwrócić uwagę na to, że często jest możliwa zamiana abstrakcyjnych typów w parametry typów klas i odwrotnie. Poniższy przykład stosuje wyłącznie parametry typów:
60+
61+
```tut
62+
abstract class Buffer[+T] {
63+
val element: T
64+
}
65+
abstract class SeqBuffer[U, +T <: Seq[U]] extends Buffer[T] {
66+
def length = element.length
67+
}
68+
object AbstractTypeTest2 extends App {
69+
def newIntSeqBuf(e1: Int, e2: Int): SeqBuffer[Int, Seq[Int]] =
70+
new SeqBuffer[Int, List[Int]] {
71+
val element = List(e1, e2)
72+
}
73+
val buf = newIntSeqBuf(7, 8)
74+
println("length = " + buf.length)
75+
println("content = " + buf.element)
76+
}
77+
```
78+
79+
Należy też pamiętać o zastosowaniu [adnotacji wariancji](variance.html). Inaczej nie byłoby możliwe ukrycie konkretnego typu sekwencji obiektu zwracanego przez metodę `newIntSeqBuf`.

Diff for: pl/tutorials/tour/annotations.md

+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
---
2+
layout: tutorial
3+
title: Adnotacje
4+
5+
disqus: true
6+
7+
tutorial: scala-tour
8+
num: 31
9+
tutorial-next: default-parameter-values
10+
tutorial-previous: automatic-closures
11+
language: pl
12+
---
13+
14+
Adnotacje dodają meta-informacje do różnego rodzaju definicji.
15+
16+
Podstawową formą adnotacji jest `@C` lub `@C(a1, ..., an)`. Tutaj `C` jest konstruktorem klasy `C`, który musi odpowiadać klasie `scala.Annotation`. Wszystkie argumenty konstruktora `a1, ..., an` muszą być stałymi wyrażeniami (czyli wyrażeniami takimi jak liczby, łańcuchy znaków, literały klasowe, enumeracje Javy oraz ich jednowymiarowe tablice).
17+
18+
Adnotację stosuje się do pierwszej definicji lub deklaracji która po niej następuje. Możliwe jest zastosowanie więcej niż jednej adnotacji przed definicją lub deklaracją. Kolejność według której są one określone nie ma istotnego znaczenia.
19+
20+
Znaczenie adnotacji jest zależne od implementacji. Na platformie Java, poniższe adnotacje domyślnie oznaczają:
21+
22+
| Scala | Java |
23+
| ------ | ------ |
24+
| [`scala.SerialVersionUID`](http://www.scala-lang.org/api/2.9.1/scala/SerialVersionUID.html) | [`serialVersionUID`](http://java.sun.com/j2se/1.5.0/docs/api/java/io/Serializable.html#navbar_bottom) (pole) |
25+
| [`scala.cloneable`](http://www.scala-lang.org/api/2.9.1/scala/cloneable.html) | [`java.lang.Cloneable`](http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Cloneable.html) |
26+
| [`scala.deprecated`](http://www.scala-lang.org/api/2.9.1/scala/deprecated.html) | [`java.lang.Deprecated`](http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Deprecated.html) |
27+
| [`scala.inline`](http://www.scala-lang.org/api/2.9.1/scala/inline.html) (since 2.6.0) | brak odpowiednika |
28+
| [`scala.native`](http://www.scala-lang.org/api/2.9.1/scala/native.html) (since 2.6.0) | [`native`](http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html) (słowo kluczowe) |
29+
| [`scala.remote`](http://www.scala-lang.org/api/2.9.1/scala/remote.html) | [`java.rmi.Remote`](http://java.sun.com/j2se/1.5.0/docs/api/java/rmi/Remote.html) |
30+
| [`scala.serializable`](http://www.scala-lang.org/api/2.9.1/index.html#scala.annotation.serializable) | [`java.io.Serializable`](http://java.sun.com/j2se/1.5.0/docs/api/java/io/Serializable.html) |
31+
| [`scala.throws`](http://www.scala-lang.org/api/2.9.1/scala/throws.html) | [`throws`](http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html) (słowo kluczowe) |
32+
| [`scala.transient`](http://www.scala-lang.org/api/2.9.1/scala/transient.html) | [`transient`](http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html) (słowo kluczowe) |
33+
| [`scala.unchecked`](http://www.scala-lang.org/api/2.9.1/scala/unchecked.html) (od 2.4.0) | brak odpowiednika |
34+
| [`scala.volatile`](http://www.scala-lang.org/api/2.9.1/scala/volatile.html) | [`volatile`](http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html) (słowo kluczowe) |
35+
| [`scala.reflect.BeanProperty`](http://www.scala-lang.org/api/2.9.1/scala/reflect/BeanProperty.html) | [`Design pattern`](http://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html) |
36+
37+
W poniższym przykładzie dodajemy adnotację `throws` do definicji metody `read` w celu obsługi rzuconego wyjątku w programie w Javie.
38+
39+
> Kompilator Javy sprawdza czy program zawiera obsługę dla [wyjątków kontrolowanych](http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html) poprzez sprawdzenie, które wyjątki mogą być wynikiem wykonania metody lub konstruktora. Dla każdego kontrolowanego wyjątku który może być wynikiem wykonania, adnotacja **throws** musi określić klasę tego wyjątku lub jedną z jej klas bazowych.
40+
> Ponieważ Scala nie pozwala na definiowanie wyjątków kontrolowanych, jeżeli chcemy obsłużyć wyjątek z kodu w Scali w Javie, należy dodać jedną lub więcej adnotacji `throws` określającej klasy wyjątków przez nią rzucanych.
41+
42+
```
43+
package examples
44+
import java.io._
45+
class Reader(fname: String) {
46+
private val in = new BufferedReader(new FileReader(fname))
47+
@throws(classOf[IOException])
48+
def read() = in.read()
49+
}
50+
```
51+
52+
Poniższy program w Javie wypisuje zawartość pliku, którego nazwa jest podana jako pierwszy argument w metodzie `main`:
53+
54+
```
55+
package test;
56+
import examples.Reader; // Klasa Scali !!
57+
public class AnnotaTest {
58+
public static void main(String[] args) {
59+
try {
60+
Reader in = new Reader(args[0]);
61+
int c;
62+
while ((c = in.read()) != -1) {
63+
System.out.print((char) c);
64+
}
65+
} catch (java.io.IOException e) {
66+
System.out.println(e.getMessage());
67+
}
68+
}
69+
}
70+
```
71+
72+
Zakomentowanie adnotacji `throws` w klasie `Reader` spowoduje poniższy błąd kompilacji głównego programu w Javie:
73+
74+
```
75+
Main.java:11: exception java.io.IOException is never thrown in body of
76+
corresponding try statement
77+
} catch (java.io.IOException e) {
78+
^
79+
1 error
80+
```
81+
82+
### Adnotacje Javy ###
83+
84+
Java w wersji 1.5 wprowadziła możliwość definiowania metadanych przez użytkownika w postaci [adnotacji](https://docs.oracle.com/javase/tutorial/java/annotations/). Kluczową cechą adnotacji jest to, że polegają one na określaniu par nazwa-wartość w celu inicjalizacji jej elementów. Na przykład, jeżeli potrzebujemy adnotacji w celu śledzenia źródeł pewnej klasy, możemy ją zdefiniować w następujący sposób:
85+
86+
```
87+
@interface Source {
88+
public String URL();
89+
public String mail();
90+
}
91+
```
92+
93+
I następnie zastosować w taki sposób:
94+
95+
```
96+
@Source(URL = "http://coders.com/",
97+
98+
public class MyClass extends HisClass ...
99+
```
100+
101+
Zastosowanie adnotacji w Scali wygląda podobnie jak wywołanie konstruktora, gdzie wymagane jest podanie nazwanych argumentów:
102+
103+
```
104+
@Source(URL = "http://coders.com/",
105+
106+
class MyScalaClass ...
107+
```
108+
109+
Składnia ta może się wydawać nieco nadmiarowa, jeżeli adnotacja składa się tylko z jednego elementu (bez wartości domyślnej), zatem jeżeli nazwa pola jest określona jako `value`, może być ona stosowana w Javie stosując składnię podobną do konstruktora:
110+
111+
```
112+
@interface SourceURL {
113+
public String value();
114+
public String mail() default "";
115+
}
116+
```
117+
118+
Następnie ją można zastosować:
119+
120+
```
121+
@SourceURL("http://coders.com/")
122+
public class MyClass extends HisClass ...
123+
```
124+
125+
W tym przypadku, Scala daje taką samą możliwość:
126+
127+
```
128+
@SourceURL("http://coders.com/")
129+
class MyScalaClass ...
130+
```
131+
132+
Element `mail` został zdefiniowany z wartością domyślną, zatem nie musimy jawnie określać wartości dla niego. Jednakże, jeżeli chcemy tego dokonać, Java nie pozwala nam na mieszanie tych styli:
133+
134+
```
135+
@SourceURL(value = "http://coders.com/",
136+
137+
public class MyClass extends HisClass ...
138+
```
139+
140+
Scala daje nam większą elastyczność w tym aspekcie:
141+
142+
```
143+
@SourceURL("http://coders.com/",
144+
145+
class MyScalaClass ...
146+
```

Diff for: pl/tutorials/tour/anonymous-function-syntax.md

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
layout: tutorial
3+
title: Funkcje anonimowe
4+
5+
disqus: true
6+
7+
tutorial: scala-tour
8+
num: 6
9+
language: pl
10+
tutorial-next: higher-order-functions
11+
tutorial-previous: mixin-class-composition
12+
---
13+
14+
Scala posiada lekką składnię pozwalającą na definiowanie funkcji anonimowych. Poniższe wyrażenie tworzy funkcję następnika dla liczb całkowitych:
15+
16+
```tut
17+
(x: Int) => x + 1
18+
```
19+
20+
Jest to krótsza forma deklaracji anonimowej klasy:
21+
22+
```tut
23+
new Function1[Int, Int] {
24+
def apply(x: Int): Int = x + 1
25+
}
26+
```
27+
28+
Możliwe jest także zdefiniowanie funkcji z wieloma parametrami:
29+
30+
```tut
31+
(x: Int, y: Int) => "(" + x + ", " + y + ")"
32+
```
33+
34+
lub też bez parametrów:
35+
36+
```tut
37+
() => { System.getProperty("user.dir") }
38+
```
39+
40+
Istnieje także prosty sposób definicji typów funkcji. Dla powyższych funkcji można je określić w następujący sposób:
41+
42+
```
43+
Int => Int
44+
(Int, Int) => String
45+
() => String
46+
```
47+
48+
Jest to skrócona forma dla poniższych typów:
49+
50+
```
51+
Function1[Int, Int]
52+
Function2[Int, Int, String]
53+
Function0[String]
54+
```

Diff for: pl/tutorials/tour/automatic-closures.md

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
---
2+
layout: tutorial
3+
title: Automatyczna konstrukcja domknięć
4+
5+
disqus: true
6+
7+
tutorial: scala-tour
8+
num: 30
9+
language: pl
10+
tutorial-next: annotations
11+
tutorial-previous: operators
12+
---
13+
14+
Scala pozwala na przekazywanie funkcji bezparametrycznych jako argumenty dla metod. Kiedy tego typu metoda jest wywołana, właściwe parametry dla funkcji bezparametrycznych nie są ewaluowane i przekazywana jest pusta funkcja, która enkapsuluje obliczenia odpowiadającego parametru (tzw. *wywołanie-przez-nazwę*).
15+
16+
Poniższy kod demonstruje działanie tego mechanizmu:
17+
18+
```tut
19+
object TargetTest1 extends App {
20+
def whileLoop(cond: => Boolean)(body: => Unit): Unit =
21+
if (cond) {
22+
body
23+
whileLoop(cond)(body)
24+
}
25+
var i = 10
26+
whileLoop (i > 0) {
27+
println(i)
28+
i -= 1
29+
}
30+
}
31+
```
32+
33+
Funkcja `whileLoop` pobiera dwa parametry: `cond` i `body`. Kiedy funkcja jest aplikowana, jej właściwe parametry nie są ewaluowane. Lecz gdy te parametry są wykorzystane w ciele `whileLoop`, zostanie ewaluowana niejawnie utworzona funkcja, zwracająca ich prawdziwą wartość. Zatem metoda `whileLoop` implementuje rekursywnie pętlę while w stylu Javy.
34+
35+
Możemy połączyć ze sobą wykorzystanie [operatorów infiksowych/postfiksowych](operators.html) z tym mechanizmem aby utworzyć bardziej złożone wyrażenia.
36+
37+
Oto implementacja pętli w stylu wykonaj-dopóki:
38+
39+
```tut
40+
object TargetTest2 extends App {
41+
def loop(body: => Unit): LoopUnlessCond =
42+
new LoopUnlessCond(body)
43+
protected class LoopUnlessCond(body: => Unit) {
44+
def unless(cond: => Boolean) {
45+
body
46+
if (!cond) unless(cond)
47+
}
48+
}
49+
var i = 10
50+
loop {
51+
println("i = " + i)
52+
i -= 1
53+
} unless (i == 0)
54+
}
55+
```
56+
57+
Funkcja `loop` przyjmuje ciało pętli oraz zwraca instancję klasy `LoopUnlessCond` (która enkapsuluje to ciało). Warto zwrócić uwagę, że ciało tej funkcji nie zostało jeszcze ewaluowane. Klasa `LoopUnlessCond` posiada metodę `unless`, którą możemy wykorzystać jako *operator infiksowy*. W ten sposób, uzyskaliśmy całkiem naturalną składnię dla naszej nowej pętli: `loop { < stats > } unless ( < cond > )`.
58+
59+
Oto wynik działania programu `TargetTest2`:
60+
61+
```
62+
i = 10
63+
i = 9
64+
i = 8
65+
i = 7
66+
i = 6
67+
i = 5
68+
i = 4
69+
i = 3
70+
i = 2
71+
i = 1
72+
```
73+

0 commit comments

Comments
 (0)