Skip to content

Polish translation of the Scala tutorial #652

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 8, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions pl/tutorials/tour/abstract-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
layout: tutorial
title: Typy abstrakcyjne

disqus: true

tutorial: scala-tour
num: 22
languages: [ba, es, ko, pl]
language: pl
tutorial-next: compound-types
tutorial-previous: inner-classes
---

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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There shouldn't be , after Scali, tbh.


Poniższy przykład definiuje wartość określaną przez abstrakcyjny typ będący elementem [cechy](traits.html) `Buffer`:

```tut
trait Buffer {
type T
val element: T
}
```

*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).

W poniższym programie definiujemy klasę `SeqBuffer`, która ogranicza możliwe typy `T` do pochodnych sekwencji `Seq[U]` dla nowego typu `U`:

```tut
abstract class SeqBuffer extends Buffer {
type U
type T <: Seq[U]
def length = element.length
}
```

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:
Copy link
Contributor

@mpociecha mpociecha Feb 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would consider adding comma after zilustrować.


```tut
abstract class IntSeqBuffer extends SeqBuffer {
type U = Int
}

object AbstractTypeTest1 extends App {
def newIntSeqBuf(elem1: Int, elem2: Int): IntSeqBuffer =
new IntSeqBuffer {
type T = List[U]
val element = List(elem1, elem2)
}
val buf = newIntSeqBuf(7, 8)
println("length = " + buf.length)
println("content = " + buf.element)
}
```

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]`.

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:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without na to it would sound better,


```tut
abstract class Buffer[+T] {
val element: T
}
abstract class SeqBuffer[U, +T <: Seq[U]] extends Buffer[T] {
def length = element.length
}
object AbstractTypeTest2 extends App {
def newIntSeqBuf(e1: Int, e2: Int): SeqBuffer[Int, Seq[Int]] =
new SeqBuffer[Int, List[Int]] {
val element = List(e1, e2)
}
val buf = newIntSeqBuf(7, 8)
println("length = " + buf.length)
println("content = " + buf.element)
}
```

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`.
146 changes: 146 additions & 0 deletions pl/tutorials/tour/annotations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
---
layout: tutorial
title: Adnotacje

disqus: true

tutorial: scala-tour
num: 31
tutorial-next: default-parameter-values
tutorial-previous: automatic-closures
language: pl
---

Adnotacje dodają meta-informacje do różnego rodzaju definicji.

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).

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.

Znaczenie adnotacji jest zależne od implementacji. Na platformie Java, poniższe adnotacje domyślnie oznaczają:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There shouldn't be comma after Java.


| Scala | Java |
| ------ | ------ |
| [`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) |
| [`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) |
| [`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) |
| [`scala.inline`](http://www.scala-lang.org/api/2.9.1/scala/inline.html) (since 2.6.0) | brak odpowiednika |
| [`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) |
| [`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) |
| [`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) |
| [`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) |
| [`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) |
| [`scala.unchecked`](http://www.scala-lang.org/api/2.9.1/scala/unchecked.html) (od 2.4.0) | brak odpowiednika |
| [`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) |
| [`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) |

W poniższym przykładzie dodajemy adnotację `throws` do definicji metody `read` w celu obsługi rzuconego wyjątku w programie w Javie.

> 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.
> 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.

```
package examples
import java.io._
class Reader(fname: String) {
private val in = new BufferedReader(new FileReader(fname))
@throws(classOf[IOException])
def read() = in.read()
}
```

Poniższy program w Javie wypisuje zawartość pliku, którego nazwa jest podana jako pierwszy argument w metodzie `main`:

```
package test;
import examples.Reader; // Klasa Scali !!
public class AnnotaTest {
public static void main(String[] args) {
try {
Reader in = new Reader(args[0]);
int c;
while ((c = in.read()) != -1) {
System.out.print((char) c);
}
} catch (java.io.IOException e) {
System.out.println(e.getMessage());
}
}
}
```

Zakomentowanie adnotacji `throws` w klasie `Reader` spowoduje poniższy błąd kompilacji głównego programu w Javie:

```
Main.java:11: exception java.io.IOException is never thrown in body of
corresponding try statement
} catch (java.io.IOException e) {
^
1 error
```

### Adnotacje Javy ###

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:

```
@interface Source {
public String URL();
public String mail();
}
```

I następnie zastosować w taki sposób:

```
@Source(URL = "http://coders.com/",
mail = "[email protected]")
public class MyClass extends HisClass ...
```

Zastosowanie adnotacji w Scali wygląda podobnie jak wywołanie konstruktora, gdzie wymagane jest podanie nazwanych argumentów:

```
@Source(URL = "http://coders.com/",
mail = "[email protected]")
class MyScalaClass ...
```

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:

```
@interface SourceURL {
public String value();
public String mail() default "";
}
```

Następnie ją można zastosować:

```
@SourceURL("http://coders.com/")
public class MyClass extends HisClass ...
```

W tym przypadku, Scala daje taką samą możliwość:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without comma after przypadku.


```
@SourceURL("http://coders.com/")
class MyScalaClass ...
```

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:

```
@SourceURL(value = "http://coders.com/",
mail = "[email protected]")
public class MyClass extends HisClass ...
```

Scala daje nam większą elastyczność w tym aspekcie:

```
@SourceURL("http://coders.com/",
mail = "[email protected]")
class MyScalaClass ...
```
54 changes: 54 additions & 0 deletions pl/tutorials/tour/anonymous-function-syntax.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
layout: tutorial
title: Funkcje anonimowe

disqus: true

tutorial: scala-tour
num: 6
language: pl
tutorial-next: higher-order-functions
tutorial-previous: mixin-class-composition
---

Scala posiada lekką składnię pozwalającą na definiowanie funkcji anonimowych. Poniższe wyrażenie tworzy funkcję następnika dla liczb całkowitych:

```tut
(x: Int) => x + 1
```

Jest to krótsza forma deklaracji anonimowej klasy:

```tut
new Function1[Int, Int] {
def apply(x: Int): Int = x + 1
}
```

Możliwe jest także zdefiniowanie funkcji z wieloma parametrami:

```tut
(x: Int, y: Int) => "(" + x + ", " + y + ")"
```

lub też bez parametrów:

```tut
() => { System.getProperty("user.dir") }
```

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:

```
Int => Int
(Int, Int) => String
() => String
```

Jest to skrócona forma dla poniższych typów:

```
Function1[Int, Int]
Function2[Int, Int, String]
Function0[String]
```
73 changes: 73 additions & 0 deletions pl/tutorials/tour/automatic-closures.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
layout: tutorial
title: Automatyczna konstrukcja domknięć

disqus: true

tutorial: scala-tour
num: 30
language: pl
tutorial-next: annotations
tutorial-previous: operators
---

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ę*).

Poniższy kod demonstruje działanie tego mechanizmu:

```tut
object TargetTest1 extends App {
def whileLoop(cond: => Boolean)(body: => Unit): Unit =
if (cond) {
body
whileLoop(cond)(body)
}
var i = 10
whileLoop (i > 0) {
println(i)
i -= 1
}
}
```

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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without comma after funkcja.


Możemy połączyć ze sobą wykorzystanie [operatorów infiksowych/postfiksowych](operators.html) z tym mechanizmem aby utworzyć bardziej złożone wyrażenia.

Oto implementacja pętli w stylu wykonaj-dopóki:

```tut
object TargetTest2 extends App {
def loop(body: => Unit): LoopUnlessCond =
new LoopUnlessCond(body)
protected class LoopUnlessCond(body: => Unit) {
def unless(cond: => Boolean) {
body
if (!cond) unless(cond)
}
}
var i = 10
loop {
println("i = " + i)
i -= 1
} unless (i == 0)
}
```

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 > )`.

Oto wynik działania programu `TargetTest2`:

```
i = 10
i = 9
i = 8
i = 7
i = 6
i = 5
i = 4
i = 3
i = 2
i = 1
```

Loading