diff options
Diffstat (limited to 'de-de')
| -rw-r--r-- | de-de/bash-de.html.markdown | 223 | ||||
| -rw-r--r-- | de-de/git-de.html.markdown | 30 | ||||
| -rw-r--r-- | de-de/go-de.html.markdown | 23 | ||||
| -rw-r--r-- | de-de/haskell-de.html.markdown | 101 | ||||
| -rw-r--r-- | de-de/scala-de.html.markdown | 518 | ||||
| -rw-r--r-- | de-de/yaml-de.html.markdown | 4 | 
6 files changed, 567 insertions, 332 deletions
diff --git a/de-de/bash-de.html.markdown b/de-de/bash-de.html.markdown index fb9cd9d4..541d28bb 100644 --- a/de-de/bash-de.html.markdown +++ b/de-de/bash-de.html.markdown @@ -28,18 +28,50 @@ echo Hello, world!  echo 'Dies ist die erste Zeile'; echo 'Dies die zweite Zeile'  # Variablen deklariert man so: -VARIABLE="irgendein String" +Variable="irgendein String"  # Aber nicht so: -VARIABLE = "irgendein String" -# Bash wird VARIABLE für einen Befehl halten, den es ausführen soll. Es wird einen Fehler ausgeben,  +Variable = "irgendein String" +# Bash wird 'Variable' für einen Befehl halten, den es ausführen soll. Es wird einen Fehler ausgeben,   # weil es den Befehl nicht findet.  +# Und so auch nicht: +Variable= 'Some string' +# Bash wird 'Variable' wieder für einen Befehl halten, den es ausführen soll. Es wird einen Fehler ausgeben,  +# Hier wird der Teil 'Variable=' als nur für diesen einen Befehl gültige Zuweisung an die Variable gesehen. +  # Eine Variable wird so benutzt: -echo $VARIABLE -echo "$VARIABLE" -# Wenn du eine Variable selbst benutzt – ihr Werte zuweist, sie exportierst oder irgendetwas anders –,  +echo $Variable +echo "$Variable" +echo ${Variable} +# aber +echo '$Variable' +# Wenn du eine Variable selbst benutzt – ihr Werte zuweist, sie exportierst oder irgendetwas anderes –,   # dann über ihren Namen ohne $. Aber wenn du ihren zugewiesenen Wert willst, dann musst du $ voranstellen. +# Beachte: ' (Hochkomma) verhindert das Interpretieren der Variablen + +# Ersetzen von Zeichenketten in Variablen +echo ${Variable/irgendein/neuer} +# Ersetzt das erste Vorkommen von "irgendein" durch "neuer" + +# Teil einer Zeichenkette +Laenge=7 +echo ${Variable:0:Laenge} +# Gibt nur die ersten 7 Zeichen zurück + +# Standardwert verwenden +echo ${Foo:-"ErsatzWennLeerOderUngesetzt"} +# Das funktioniert mit nicht gesetzten Variablen (Foo=) und leeren Zeichenketten (Foo="") +# Die Zahl 0 (Foo=0) liefert 0. +# Beachte: der wert der Variablen wird nicht geändert + +# Eingebaute Variable (BUILTINS): +# Einige nützliche Beispiele +echo "Rückgabewert des letzten Befehls: $?" +echo "Die PID des skripts: $$" +echo "Anzahl der Argumente beim Aufruf: $#" +echo "Alle Argumente beim Aufruf: $@" +echo "Die Argumente in einzelnen Variablen: $1 $2..."  # Einen Wert aus der Eingabe lesen:  echo "Wie heisst du?" @@ -47,14 +79,30 @@ read NAME # Wir mussten nicht mal eine neue Variable deklarieren  echo Hello, $NAME!  # Wir haben die übliche if-Struktur: -if true +# 'man test' liefert weitere Informationen zu Bedingungen +if [ "$NAME" -ne $USER ]  then -    echo "Wie erwartet" +    echo "Dein Name ist nicht dein Login-Name"  else -    echo "Und dies nicht" +    echo "Dein Name ist dein Login-Name" +fi + +# Es gibt auch bedingte Ausführung +echo "immer ausgeführt" || echo "Nur ausgeführt wenn der erste Befehl fehlschlägt" +echo "immer ausgeführt" && echo "Nur ausgeführt wenn der erste Befehl Erfolg hat" + +# Um && und || mit if statements zu verwenden, braucht man mehrfache Paare eckiger Klammern: +if [ $NAME == "Steve" ] && [ $Alter -eq 15 ] +then +    echo "Wird ausgeführt wenn $NAME gleich 'Steve' UND $Alter gleich 15." +fi + +if [ $Name == "Daniya" ] || [ $Name == "Zach" ] +then +    echo "Wird ausgeführt wenn $NAME gleich 'Daniya' ODER $NAME gleich 'Zach'."  fi -# Ausdrücke werden im folgenden Format festgehalten: +# Ausdrücke haben folgendes Format:  echo $(( 10 + 5 ))  # Anders als andere Programmiersprachen ist Bash eine Shell – es arbeitet also im Kontext von Verzeichnissen. @@ -69,13 +117,60 @@ ls -l # Liste alle Dateien und Unterverzeichnisse auf einer eigenen Zeile auf  # txt-Dateien im aktuellen Verzeichnis auflisten:  ls -l | grep "\.txt" -# Befehle können innerhalb anderer Befehle mit $( ) erstetzt werden: +# Ein- und Ausgabe können umgeleitet werden (stdin, stdout, and stderr). +# Von stdin lesen bis "EOF" allein in einer Zeile auftaucht +# und die Datei hello.py mit den Zeilen zwischen den beiden "EOF" +# überschreiben: +cat > hello.py << EOF +#!/usr/bin/env python +from __future__ import print_function +import sys +print("#stdout", file=sys.stdout) +print("#stderr", file=sys.stderr) +for line in sys.stdin: +    print(line, file=sys.stdout) +EOF + +# Führe hello.py mit verschiedenen Umleitungen von +# stdin, stdout und stderr aus: +python hello.py < "input.in" +python hello.py > "output.out" +python hello.py 2> "error.err" +python hello.py > "output-and-error.log" 2>&1 +python hello.py > /dev/null 2>&1 +# Die Fehlerausgabe würde die Datei "error.err" überschreiben (falls sie existiert)  +# verwende ">>" um stattdessen anzuhängen: +python hello.py >> "output.out" 2>> "error.err" + +# Überschreibe output.out, hänge an error.err an und zähle die Zeilen beider Dateien: +info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err +wc -l output.out error.err + +# Führe einen Befehl aus und gib dessen "file descriptor" (zB /dev/fd/123) aus +# siehe: man fd +echo <(echo "#helloworld") + +# Mehrere Arten, um output.out mit "#helloworld" zu überschreiben: +cat > output.out <(echo "#helloworld") +echo "#helloworld" > output.out +echo "#helloworld" | cat > output.out +echo "#helloworld" | tee output.out >/dev/null + +# Löschen der Hilfsdateien von oberhalb, mit Anzeige der Dateinamen +# (mit '-i' für "interactive" erfolgt für jede Date eine Rückfrage) +rm -v output.out error.err output-and-error.log + +# Die Ausgabe von Befehlen kann mit Hilfe von $( ) in anderen Befehlen verwendet weden:  # Der folgende Befehl zeigt die Anzahl aller Dateien und Unterverzeichnisse  # im aktuellen Verzeichnis an.  echo "Dieser Ordner beinhaltet $(ls | wc -l) Dateien und Verzeichnisse." +# Dasselbe kann man mit "backticks" `` erreichen, aber diese können +# nicht verschachtelt werden. $() ist die empfohlene Methode. +echo "Dieser Ordner beinhaltet `ls | wc -l` Dateien und Verzeichnisse." +  # Bash nutzt einen case-Ausdruck, der sich ähnlich wie switch in Java oder C++ verhält. -case "$VARIABLE" +case "$Variable"  in      # Liste der Fälle, die unterschieden werden sollen      0) echo "Hier ist eine Null." @@ -83,10 +178,106 @@ in      *) echo "Das ist nicht Null."  esac -# loops iterieren über die angegebene Zahl von Argumenten: -# Der Inhalt von $VARIABLE wird dreimal ausgedruckt. -for $VARIABLE in x y z +# 'for' Schleifen iterieren über die angegebene Zahl von Argumenten: +# Der Inhalt von $Variable wird dreimal ausgedruckt. +for $Variable in {1..3}  do -    echo "$VARIABLE" +    echo "$Variable"  done + +# Oder verwende die "traditionelle 'for'-Schleife": +for ((a=1; a <= 3; a++)) +do +    echo $a +done + +# Schleifen können auch mit Dateien arbeiten: +# 'cat' zeigt zuerst file1 an und dann file2 +for Variable in file1 file2 +do +    cat "$Variable" +done + +# .. oder mit der Ausgabe eines Befehls: +# Ausgabe des Inhalts jeder Datei, die von 'ls' aufgezählt wird +for Output in $(ls) +do +    cat "$Output" +done + +# while Schleife: +while [ true ] +do +    echo "Schleifenkörper..." +    break +done + +# Funktionen definieren +# Definition: +function foo () +{ +    echo "Argumente funktionieren wie bei skripts: $@" +    echo Und: $1 $2..." +    echo "Dies ist eine Funktion" +    return 0 +} + +# oder einfacher +bar () +{ +    echo "Auch so kann man Funktionen deklarieren!" +    return 0 +} + +# Aufruf der Funktion: +foo "My name is" $Name + +# Was du noch lernen könntest: +# Ausgabe der letzten 10 Zeilen von file.txt +tail -n 10 file.txt +# Ausgabe der ersten 10 Zeilen von file.txt +head -n 10 file.txt +# sortierte Ausgabe von file.txt +sort file.txt +# Mehrfachzeilen in sortierten Dateien unterdrücken +# oder (mit -d) nur diese ausgeben +uniq -d file.txt +# Ausgabe nur der ersten Spalte (vor dem ersten ',') +cut -d ',' -f 1 file.txt +# ersetze in file.txt jedes vorkommende 'gut' durch 'super' (versteht regex) +sed -i 's/gut/super/g' file.txt +# Ausgabe nach stdout aller Zeilen von file.txt, die auf eine regex passen +# Im Beispiel: Zeilen, die mit "foo" beginnen und mit "bar" enden +grep "^foo.*bar$" file.txt +# Mit der Option "-c" wird stattdessen die Anzahl der gefundenen Zeilen ausgegeben +grep -c "^foo.*bar$" file.txt +# verwende 'fgrep' oder 'grep -F' wenn du buchstäblich nach den Zeichen +# suchen willst, ohne sie als regex zu interpretieren +fgrep "^foo.*bar$" file.txt + +# Dokumentation über die in bash eingebauten Befehle +# bekommst du mit dem eingebauten Befehl 'help' +help +help help +help for +help return +help source +help . + +# Das bash-Handbuch liest du mit 'man' +apropos bash +man 1 bash +man bash + +# Dann gibt es noch das 'info' System (drücke ? um Hilfe angezeigt zu bekommen) +apropos info | grep '^info.*(' +man info +info info +info 5 info + +# info Dokumentation über bash: +info bash +info bash 'Bash Features' +info bash 6 +info --apropos bash  ``` diff --git a/de-de/git-de.html.markdown b/de-de/git-de.html.markdown index 43939129..dea329d5 100644 --- a/de-de/git-de.html.markdown +++ b/de-de/git-de.html.markdown @@ -18,12 +18,12 @@ Anmerkung des Übersetzers: Einige englische Begriffe wie *Repository*, *Commit*  ### Was ist Versionsverwaltung? -Eine Versionskontrolle erfasst die Änderungen einer Datei oder eines Verzeichnisses im Verlauf der Zeit. +Eine Versionsverwaltung erfasst die Änderungen einer Datei oder eines Verzeichnisses im Verlauf der Zeit.  ### Zentrale im Vergleich mit verteilter Versionverwaltung -* Zentrale Versionskontrolle konzentriert sich auf das Synchronisieren, Verfolgen und Sichern von Dateien. -* Verteilte Versionskontrolle konzentriert sich auf das Teilen der Änderungen. Jede Änderung hat eine eindeutige ID. +* Zentrale Versionsverwaltung konzentriert sich auf das Synchronisieren, Verfolgen und Sichern von Dateien. +* Verteilte Versionsverwaltung konzentriert sich auf das Teilen der Änderungen. Jede Änderung hat eine eindeutige ID.  * Verteilte Systeme haben keine vorbestimmte Struktur. Ein SVN-ähnliches, zentrales System wäre mit Git ebenso umsetzbar.  [Weiterführende Informationen](http://git-scm.com/book/en/Getting-Started-About-Version-Control) @@ -61,7 +61,7 @@ Der Index ist die die Staging-Area von Git. Es ist im Grunde eine Ebene, die Arb  ### Commit -Ein Commit ist ein Schnappschuss von Uderungen in deinem Arbeitsverzeichnis. Wenn du zum Beispiel 5 Dateien hinzugefügt und 2 andere entfernt hast, werden diese Änderungen im Commit (Schnappschuss) enthalten sein. Dieser Commit kann dann in andere Repositorys gepusht werden. Oder nicht! +Ein Commit ist ein Schnappschuss von Änderungen in deinem Arbeitsverzeichnis. Wenn du zum Beispiel 5 Dateien hinzugefügt und 2 andere entfernt hast, werden diese Änderungen im Commit (Schnappschuss) enthalten sein. Dieser Commit kann dann in andere Repositories gepusht werden. Oder nicht!  ### Branch @@ -69,7 +69,9 @@ Ein Branch, ein Ast oder Zweig, ist im Kern ein Pointer auf den letzten Commit,  ### HEAD und head (Teil des .git-Verzeichnisses) -HEAD ist ein Pointer auf den aktuellen Branch. Ein Repository hat nur einen *aktiven* HEAD. Ein head ist ein Pointer, der auf ein beliebige Zahl von heads zeigt. +HEAD ist ein Pointer auf den aktuellen Branch. Ein Repository hat nur einen *aktiven* HEAD.  + +Ein *head* ist ein Pointer, der auf einen beliebigen Commit zeigt.  Ein Repository kann eine beliebige Zahl von *heads* enthalten.  ### Konzeptionelle Hintergründe @@ -127,7 +129,7 @@ Zeigt die Unterschiede zwischen Index (im Grunde dein Arbeitsverzeichnis/-reposi  ```bash -# Zeigt den Branch, nicht-verfolgte Dateien, Uderungen und andere Unterschiede an +# Zeigt den Branch, nicht-verfolgte Dateien, Änderungen und andere Unterschiede an  $ git status  # Anderes Wissenswertes über git status anzeigen @@ -151,7 +153,7 @@ $ git add ./*.java  ### branch -Verwalte alle Branches. Du kannst sie mit diesem Befehl ansehen, bearbeiten, neue erschaffen oder löschen. +Verwalte alle Branches. Du kannst sie mit diesem Befehl ansehen, bearbeiten, neue erzeugen oder löschen.  ```bash  # Liste alle bestehenden Branches und Remotes auf @@ -186,7 +188,7 @@ $ git checkout -b newBranch  ### clone -Ein bestehendes Repository in ein neues Verzeichnis klonen oder kopieren. Es fügt außerdem für hedes geklonte Repo remote-tracking Branches hinzu. Du kannst auf diese Remote-Branches pushen. +Ein bestehendes Repository in ein neues Verzeichnis klonen oder kopieren. Es fügt außerdem für jedes geklonte Repository remote-tracking Branches hinzu. Du kannst auf diese Remote-Branches pushen.  ```bash  # Klone learnxinyminutes-docs @@ -288,16 +290,16 @@ $ git mv -f myFile existingFile  ### pull -Führe einen Pull, zieht alle Daten, eines Repositorys und f?? einen Merge mit einem anderen Branch durch. +Führe einen Pull (zieht alle Daten eines Repositories) aus und führt einen Merge mit einem anderen Branch durch.  ```bash -# Update deines lokalen Repos, indem ein Merge der neuen Uderungen -# von den remote-liegenden "origin"- und "master"-Branches durchgef?? wird. +# Update deines lokalen Repos, indem ein Merge der neuen Änderungen +# von den remote-liegenden "origin"- und "master"-Branches durchgeführt wird.  # git pull <remote> <branch>  # git pull => impliziter Verweis auf origin und master  $ git pull origin master -# F?? einen Merge von Uderungen eines remote-Branch und ein Rebase +# Führt einen Merge von Änderungen eines remote-Branch und ein Rebase  # des Branch-Commits im lokalen Repo durch. Wie: pull <remote> <branch>, git rebase <branch>"  $ git pull origin master --rebase  ``` @@ -337,8 +339,8 @@ $ git reset  # Setze die Staging-Area zurück, um dem letzten Commit zu entsprechen und überschreibe das Arbeitsverzeichnis  $ git reset --hard -# Bewegt die Spitze des Branches zu dem angegebenen Commit (das Verzeichnis bleibt unber??) -# Alle Uderungen bleiben im Verzeichnis erhalten +# Bewegt die Spitze des Branches zu dem angegebenen Commit (das Verzeichnis bleibt unberührt) +# Alle Änderungen bleiben im Verzeichnis erhalten  $ git reset 31f2bb1  # Bewegt die Spitze des Branches zurück zu dem angegebenen Commit diff --git a/de-de/go-de.html.markdown b/de-de/go-de.html.markdown index 765372e0..d3a192fe 100644 --- a/de-de/go-de.html.markdown +++ b/de-de/go-de.html.markdown @@ -3,6 +3,7 @@ language: Go  filename: learngo-de.go  contributors:      - ["Joseph Adams", "https://github.com/jcla1"] +    - ["Dennis Keller", "https://github.com/denniskeller"]  lang: de-de  ---  Go wurde entwickelt, um Probleme zu lösen. Sie ist zwar nicht der neueste Trend in @@ -24,7 +25,7 @@ aktive Community.     zeiliger Kommentar */  // Eine jede Quelldatei beginnt mit einer Paket-Klausel. -// "main" ist ein besonderer Pkaetname, da er ein ausführbares Programm +// "main" ist ein besonderer Paketname, da er ein ausführbares Programm  // einleitet, im Gegensatz zu jedem anderen Namen, der eine Bibliothek  // deklariert.  package main @@ -37,7 +38,7 @@ import (      "strconv"  // Zeichenkettenmanipulation  ) -// Es folgt die Definition einer Funktions, in diesem Fall von "main". Auch hier +// Es folgt die Definition einer Funktion, in diesem Fall von "main". Auch hier  // ist der Name wieder besonders. "main" markiert den Eintrittspunkt des  // Programms. Vergessen Sie nicht die geschweiften Klammern!  func main() { @@ -55,7 +56,7 @@ func beyondHello() {      var x int // Deklaration einer Variable, muss vor Gebrauch geschehen.      x = 3     // Zuweisung eines Werts.      // Kurze Deklaration: Benutzen Sie ":=", um die Typisierung automatisch zu -    // folgern, die Variable zu deklarieren und ihr einen Wert zu zuweisen. +    // folgern, die Variable zu deklarieren und ihr einen Wert zuzuweisen.      y := 4      // Eine Funktion mit mehreren Rückgabewerten. @@ -146,7 +147,7 @@ func learnFlowControl() {      if false {          // nicht hier      } else { -        // sonder hier! spielt die Musik +        // sondern hier! spielt die Musik      }      // Benutzen Sie ein "switch" Statement anstatt eine Anreihung von if-s @@ -165,7 +166,7 @@ func learnFlowControl() {      // Ab hier gilt wieder: x == 1      // For ist die einzige Schleifenform in Go, sie hat aber mehrere Formen: -    for { // Endloschleife +    for { // Endlosschleife          break    // nur ein Spaß          continue // wird nie ausgeführt      } @@ -262,10 +263,10 @@ func learnConcurrency() {      // Auslesen und dann Ausgeben der drei berechneten Werte.      // Man kann nicht im voraus feststellen in welcher Reihenfolge die Werte      // ankommen. -    fmt.Println(<-c, <-c, <-c) // mit dem Kannal rechts ist <- der Empfangs-Operator +    fmt.Println(<-c, <-c, <-c) // mit dem Kanal rechts ist <- der Empfangs-Operator -    cs := make(chan string)       // ein weiterer Kannal, diesmal für strings -    cc := make(chan chan string)  // ein Kannal für string Kannäle +    cs := make(chan string)       // ein weiterer Kanal, diesmal für strings +    cc := make(chan chan string)  // ein Kanal für string Kanäle      // Start einer neuen Goroutine, nur um einen Wert zu senden      go func() { c <- 84 }() @@ -282,7 +283,7 @@ func learnConcurrency() {          fmt.Println("wird nicht passieren.")      }      // Hier wird eine der beiden Goroutines fertig sein, die andere nicht. -    // Sie wird warten bis der Wert den sie sendet von dem Kannal gelesen wird. +    // Sie wird warten bis der Wert den sie sendet von dem Kanal gelesen wird.      learnWebProgramming() // Go kann es und Sie hoffentlich auch bald.  } @@ -300,13 +301,13 @@ func learnWebProgramming() {  // Methode implementieren: ServeHTTP  func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {      // Senden von Daten mit einer Methode des http.ResponseWriter -    w.Write([]byte("Sie habe Go in Y Minuten gelernt!")) +    w.Write([]byte("Sie haben Go in Y Minuten gelernt!"))  }  ```  ## Weitere Resourcen  Alles zu Go finden Sie auf der [offiziellen Go Webseite](http://golang.org/). -Dort können sie der Tutorial folgen, interaktiv Quelltext ausprobieren und viel +Dort können sie dem Tutorial folgen, interaktiv Quelltext ausprobieren und viel  Dokumentation lesen.  Auch zu empfehlen ist die Spezifikation von Go, die nach heutigen Standards sehr diff --git a/de-de/haskell-de.html.markdown b/de-de/haskell-de.html.markdown index 2c548961..d1a0008e 100644 --- a/de-de/haskell-de.html.markdown +++ b/de-de/haskell-de.html.markdown @@ -5,6 +5,7 @@ contributors:      - ["Adit Bhargava", "http://adit.io"]  translators:      - ["Henrik Jürges", "https://github.com/santifa"] +    - ["Nikolai Weh", "http://weh.hamburg"]  filename: haskell-de.hs  --- @@ -58,12 +59,13 @@ not False -- True  -- Strings und Zeichen  "Das ist ein String."  'a' -- Zeichen -'Einfache Anfuehrungszeichen gehen nicht.' -- error! +'Einfache Anführungszeichen gehen nicht.' -- error!  -- Strings können konkateniert werden.  "Hello " ++ "world!" -- "Hello world!"  -- Ein String ist eine Liste von Zeichen. +['H', 'a', 'l', 'l', 'o', '!'] -- "Hallo!"  "Das ist eine String" !! 0 -- 'D' @@ -76,11 +78,23 @@ not False -- True  [1, 2, 3, 4, 5]  [1..5] --- Haskell unterstuetzt unendliche Listen! -[1..] -- Die Liste aller natuerlichen Zahlen +-- Die zweite Variante nennt sich die "range"-Syntax. +-- Ranges sind recht flexibel: +['A'..'F'] -- "ABCDEF" + +-- Es ist möglich eine Schrittweite anzugeben: +[0,2..10] -- [0,2,4,6,8,10] +[5..1] -- [], da Haskell standardmässig inkrementiert. +[5,4..1] -- [5,4,3,2,1] + +-- Der "!!"-Operator extrahiert das Element an einem bestimmten Index: +[1..10] !! 3 -- 4 + +-- Haskell unterstützt unendliche Listen! +[1..] -- Die Liste aller natürlichen Zahlen  -- Unendliche Listen funktionieren in Haskell, da es "lazy evaluation" --- unterstuetzt. Haskell evaluiert erst etwas, wenn es benötigt wird. +-- unterstützt. Haskell evaluiert erst etwas, wenn es benötigt wird.  -- Somit kannst du nach dem 1000. Element fragen und Haskell gibt es dir:  [1..] !! 999 -- 1000 @@ -92,12 +106,9 @@ not False -- True  -- Zwei Listen konkatenieren  [1..5] ++ [6..10] --- Ein Element als Head hinzufuegen +-- Ein Element als Head hinzufügen  0:[1..5] -- [0, 1, 2, 3, 4, 5] --- Gibt den 5. Index zurueck -[0..] !! 5 -- 5 -  -- Weitere Listenoperationen  head [1..5] -- 1  tail [1..5] -- [2, 3, 4, 5] @@ -114,7 +125,8 @@ last [1..5] -- 5  -- Ein Tupel:  ("haskell", 1) --- Auf Elemente eines Tupels zugreifen: +-- Ein Paar (Pair) ist ein Tupel mit 2 Elementen, auf die man wie folgt +-- zugreifen kann:  fst ("haskell", 1) -- "haskell"  snd ("haskell", 1) -- 1 @@ -140,9 +152,9 @@ add 1 2 -- 3  (//) a b = a `div` b  35 // 4 -- 8 --- Guards sind eine einfache Möglichkeit fuer Fallunterscheidungen. +-- Guards sind eine einfache Möglichkeit für Fallunterscheidungen.  fib x -  | x < 2 = x +  | x < 2 = 1    | otherwise = fib (x - 1) + fib (x - 2)  -- Pattern Matching funktioniert ähnlich. @@ -174,7 +186,7 @@ foldl1 (\acc x -> acc + x) [1..5] -- 15  -- 4. Mehr Funktionen  ---------------------------------------------------- --- currying: Wenn man nicht alle Argumente an eine Funktion uebergibt, +-- currying: Wenn man nicht alle Argumente an eine Funktion übergibt,  -- so wird sie eine neue Funktion gebildet ("curried").  -- Es findet eine partielle Applikation statt und die neue Funktion  -- nimmt die fehlenden Argumente auf. @@ -190,23 +202,28 @@ foo 5 -- 15  -- Funktionskomposition  -- Die (.) Funktion verkettet Funktionen.  -- Zum Beispiel, die Funktion Foo nimmt ein Argument addiert 10 dazu und --- multipliziert dieses Ergebnis mit 5. -foo = (*5) . (+10) +-- multipliziert dieses Ergebnis mit 4. +foo = (*4) . (+10) + +-- (5 + 10) * 4 = 60 +foo 5 -- 60 --- (5 + 10) * 5 = 75 -foo 5 -- 75 +-- Haskell hat einen Operator `$`, welcher Funktionsapplikation durchführt. +-- Im Gegenzug zu der Standard-Funktionsapplikation, welche linksassoziativ ist +-- und die höchstmögliche Priorität von "10" hat, ist der `$`-Operator +-- rechtsassoziativ und hat die Priorität 0. Dieses hat (idr.) den Effekt, +-- dass der `komplette` Ausdruck auf der rechten Seite als Parameter für die +-- Funktion auf der linken Seite verwendet wird. +-- Mit `.` und `$` kann man sich so viele Klammern ersparen. --- Haskell hat eine Funktion `$`. Diese ändert den Vorrang, --- so dass alles links von ihr zuerst berechnet wird und --- und dann an die rechte Seite weitergegeben wird. --- Mit `.` und `$` kann man sich viele Klammern ersparen. +(even (fib 7)) -- false --- Vorher -(even (fib 7)) -- true +-- Äquivalent: +even $ fib 7 -- false --- Danach -even . fib $ 7 -- true +-- Funktionskomposition: +even . fib $ 7 -- false  ----------------------------------------------------  -- 5. Typensystem @@ -221,31 +238,31 @@ even . fib $ 7 -- true  True :: Bool  -- Funktionen haben genauso Typen. --- `not` ist Funktion die ein Bool annimmt und ein Bool zurueckgibt: +-- `not` ist Funktion die ein Bool annimmt und ein Bool zurückgibt:  -- not :: Bool -> Bool  -- Eine Funktion die zwei Integer Argumente annimmt:  -- add :: Integer -> Integer -> Integer  -- Es ist guter Stil zu jeder Funktionsdefinition eine --- Typdefinition darueber zu schreiben: +-- Typdefinition darüber zu schreiben:  double :: Integer -> Integer  double x = x * 2  ---------------------------------------------------- --- 6. If-Anweisung und Kontrollstrukturen +-- 6. If-Ausdrücke und Kontrollstrukturen  ---------------------------------------------------- --- If-Anweisung: +-- If-Ausdruck:  haskell = if 1 == 1 then "awesome" else "awful" -- haskell = "awesome" --- If-Anweisungen können auch ueber mehrere Zeilen verteilt sein. --- Das Einruecken ist dabei äußerst wichtig. +-- If-Ausdrücke können auch über mehrere Zeilen verteilt sein. +-- Die Einrückung ist dabei wichtig.  haskell = if 1 == 1              then "awesome"              else "awful" --- Case-Anweisung: Zum Beispiel "commandline" Argumente parsen. +-- Case-Ausdruck: Am Beispiel vom Parsen von "commandline"-Argumenten.  case args of    "help" -> printHelp    "start" -> startProgram @@ -276,7 +293,7 @@ foldl (\x y -> 2*x + y) 4 [1,2,3] -- 43  foldr (\x y -> 2*x + y) 4 [1,2,3] -- 16  -- die Abarbeitung sieht so aus: -(2 * 3 + (2 * 2 + (2 * 1 + 4))) +(2 * 1 + (2 * 2 + (2 * 3 + 4)))  ----------------------------------------------------  -- 7. Datentypen @@ -300,7 +317,7 @@ data Maybe a = Nothing | Just a  -- Diese sind alle vom Typ Maybe:  Just "hello"    -- vom Typ `Maybe String`  Just 1          -- vom Typ `Maybe Int` -Nothing         -- vom Typ `Maybe a` fuer jedes `a` +Nothing         -- vom Typ `Maybe a` für jedes `a`  ----------------------------------------------------  -- 8. Haskell IO @@ -309,8 +326,8 @@ Nothing         -- vom Typ `Maybe a` fuer jedes `a`  -- IO kann nicht völlig erklärt werden ohne Monaden zu erklären,  -- aber man kann die grundlegenden Dinge erklären. --- Wenn eine Haskell Programm ausgefuehrt wird, so wird `main` aufgerufen. --- Diese muss etwas vom Typ `IO ()` zurueckgeben. Zum Beispiel: +-- Wenn eine Haskell Programm ausgeführt wird, so wird `main` aufgerufen. +-- Diese muss etwas vom Typ `IO ()` zurückgeben. Zum Beispiel:  main :: IO ()  main = putStrLn $ "Hello, sky! " ++ (say Blue) @@ -338,10 +355,10 @@ sayHello = do                     -- an die Variable "name" gebunden     putStrLn $ "Hello, " ++ name --- Uebung: Schreibe deine eigene Version von `interact`, +-- Übung: Schreibe deine eigene Version von `interact`,  -- die nur eine Zeile einliest. --- `sayHello` wird niemals ausgefuehrt, nur `main` wird ausgefuehrt. +-- `sayHello` wird niemals ausgeführt, nur `main` wird ausgeführt.  -- Um `sayHello` laufen zulassen kommentiere die Definition von `main`  -- aus und ersetze sie mit:  --     main = sayHello @@ -359,7 +376,7 @@ action = do     input1 <- getLine     input2 <- getLine     -- Der Typ von `do` ergibt sich aus der letzten Zeile. -   -- `return` ist eine Funktion und keine Schluesselwort +   -- `return` ist eine Funktion und keine Schlüsselwort     return (input1 ++ "\n" ++ input2) -- return :: String -> IO String  -- Nun können wir `action` wie `getLine` benutzen: @@ -370,7 +387,7 @@ main'' = do      putStrLn result      putStrLn "This was all, folks!" --- Der Typ `IO` ist ein Beispiel fuer eine Monade. +-- Der Typ `IO` ist ein Beispiel für eine Monade.  -- Haskell benutzt Monaden Seiteneffekte zu kapseln und somit  -- eine rein funktional Sprache zu sein.  -- Jede Funktion die mit der Außenwelt interagiert (z.B. IO) @@ -387,7 +404,7 @@ main'' = do  -- Starte die REPL mit dem Befehl `ghci`  -- Nun kann man Haskell Code eingeben. --- Alle neuen Werte muessen mit `let` gebunden werden: +-- Alle neuen Werte müssen mit `let` gebunden werden:  let foo = 5 @@ -396,7 +413,7 @@ let foo = 5  >:t foo  foo :: Integer --- Auch jede `IO ()` Funktion kann ausgefuehrt werden. +-- Auch jede `IO ()` Funktion kann ausgeführt werden.  > sayHello  What is your name? @@ -420,6 +437,6 @@ qsort (p:xs) = qsort lesser ++ [p] ++ qsort greater  Haskell ist sehr einfach zu installieren.  Hohl es dir von [hier](http://www.haskell.org/platform/). -Eine sehr viele langsamere Einfuehrung findest du unter: +Eine sehr viele langsamere Einführung findest du unter:  [Learn you a Haskell](http://learnyouahaskell.com/) oder  [Real World Haskell](http://book.realworldhaskell.org/). diff --git a/de-de/scala-de.html.markdown b/de-de/scala-de.html.markdown index 7fd299b4..456403a2 100644 --- a/de-de/scala-de.html.markdown +++ b/de-de/scala-de.html.markdown @@ -5,6 +5,7 @@ contributors:      - ["Dominic Bou-Samra", "http://dbousamra.github.com"]      - ["Geoff Liu", "http://geoffliu.me"]      - ["Ha-Duong Nguyen", "http://reference-error.org"] +    - ["Dennis Keller", "github.com/denniskeller"]  translators:    - ["Christian Albrecht", "https://github.com/coastalchief"]  filename: learnscala-de.scala @@ -16,167 +17,172 @@ für die Java Virtual Machine (JVM), um allgemeine Programmieraufgaben  zu erledigen. Scala hat einen akademischen Hintergrund und wurde an    der EPFL (Lausanne / Schweiz) unter der Leitung von Martin Odersky entwickelt. - -# 0. Umgebung einrichten +```scala  +/*  Scala Umgebung einrichten:  1. Scala binaries herunterladen- http://www.scala-lang.org/downloads  2. Unzip/untar in ein Verzeichnis  3. das bin Unterverzeichnis der `PATH` Umgebungsvariable hinzufügen  4. Mit dem Kommando `scala` wird die REPL gestartet und zeigt als Prompt: -``` +  scala> -```  Die REPL (Read-Eval-Print Loop) ist der interaktive Scala Interpreter.    Hier kann man jeden Scala Ausdruck verwenden und das Ergebnis wird direkt    ausgegeben.    Als nächstes beschäftigen wir uns mit ein paar Scala Basics. +*/ -# 1. Basics -Einzeilige Kommentare beginnen mit zwei vorwärts Slash +///////////////////////////////////////////////// +// 1. Basics +///////////////////////////////////////////////// + +// Einzeilige Kommentare beginnen mit zwei Slashes  /* -  Mehrzeilige Kommentare, werden starten  -  mit Slash-Stern und enden mit Stern-Slash +  Mehrzeilige Kommentare, starten  +  mit einem Slash-Stern und enden mit einem Stern-Slash  */  // Einen Wert, und eine zusätzliche neue Zeile ausgeben   -``` +  println("Hello world!")  println(10) -``` +  // Einen Wert, ohne eine zusätzliche neue Zeile ausgeben   -``` +  print("Hello world") -``` -// Variablen werden entweder mit var oder val deklariert.   -// Deklarationen mit val sind immutable, also unveränderlich   -// Deklarationen mit var sind mutable, also veränderlich   -// Immutability ist gut.   -``` +/* +  Variablen werden entweder mit var oder val deklariert.   +  Deklarationen mit val sind immutable, also unveränderlich   +  Deklarationen mit var sind mutable, also veränderlich   +  Immutability ist gut.   +*/  val x = 10 // x ist 10  x = 20     // error: reassignment to val  var y = 10  y = 20     // y ist jetzt 20 -``` -Scala ist eine statisch getypte Sprache, auch wenn in dem o.g. Beispiel   +/* +Scala ist eine statisch getypte Sprache, auch wenn wir in dem o.g. Beispiel    keine Typen an x und y geschrieben haben.   -In Scala ist etwas eingebaut, was sich Type Inference nennt. D.h. das der   -Scala Compiler in den meisten Fällen erraten kann, von welchen Typ eine ist,   -so dass der Typ nicht jedes mal angegeben werden soll.   +In Scala ist etwas eingebaut, was sich Type Inference nennt. Das heißt das der   +Scala Compiler in den meisten Fällen erraten kann, von welchen Typ eine Variable ist,   +so dass der Typ nicht jedes mal angegeben werden muss.    Einen Typ gibt man bei einer Variablendeklaration wie folgt an:   -``` +*/  val z: Int = 10  val a: Double = 1.0 -``` +  // Bei automatischer Umwandlung von Int auf Double wird aus 10 eine 10.0   -``` +  val b: Double = 10 -``` +  // Boolean Werte   -``` +  true  false -``` +  // Boolean Operationen   -``` +  !true         // false  !false        // true  true == false // false  10 > 5        // true -``` +  // Mathematische Operationen sind wie gewohnt   -``` +  1 + 1   // 2  2 - 1   // 1  5 * 3   // 15  6 / 2   // 3  6 / 4   // 1  6.0 / 4 // 1.5 -``` +  // Die Auswertung eines Ausdrucks in der REPL gibt den Typ    // und das Ergebnis zurück.   -``` +    scala> 1 + 7    res29: Int = 8 -``` +/*  Das bedeutet, dass das Resultat der Auswertung von 1 + 7 ein Objekt    von Typ Int ist und einen Wert 0 hat.    "res29" ist ein sequentiell generierter name, um das Ergebnis des    Ausdrucks zu speichern. Dieser Wert kann bei Dir anders sein...   - +*/  "Scala strings werden in doppelten Anführungszeichen eingeschlossen"    'a' // A Scala Char    // 'Einzeln ge-quotete strings gibt es nicht!' <= This causes an error    // Für Strings gibt es die üblichen Java Methoden   -``` +  "hello world".length  "hello world".substring(2, 6)  "hello world".replace("C", "3") -``` +  // Zusätzlich gibt es noch extra Scala Methoden    // siehe: scala.collection.immutable.StringOps   -``` +  "hello world".take(5)  "hello world".drop(5) -``` +  // String interpolation: prefix "s"   -``` +  val n = 45  s"We have $n apples" // => "We have 45 apples" -``` -// Ausdrücke im innern von interpolierten Strings gibt es auch   -``` + +// Ausdrücke im Innern von interpolierten Strings gibt es auch   +  val a = Array(11, 9, 6)  val n = 100  s"My second daughter is ${a(0) - a(2)} years old."    // => "My second daughter is 5 years old."  s"We have double the amount of ${n / 2.0} in apples." // => "We have double the amount of 22.5 in apples."  s"Power of 2: ${math.pow(2, 2)}"                      // => "Power of 2: 4" -``` +  // Formatierung der interpolierten Strings mit dem prefix "f"   -``` +  f"Power of 5: ${math.pow(5, 2)}%1.0f"         // "Power of 5: 25"  f"Square root of 122: ${math.sqrt(122)}%1.4f" // "Square root of 122: 11.0454" -``` +  // Raw Strings, ignorieren Sonderzeichen.   -``` +  raw"New line feed: \n. Carriage return: \r." // => "New line feed: \n. Carriage return: \r." -``` +  // Manche Zeichen müssen "escaped" werden, z.B.     // ein doppeltes Anführungszeichen in innern eines Strings.   -``` +  "They stood outside the \"Rose and Crown\"" // => "They stood outside the "Rose and Crown"" -``` +  // Dreifache Anführungszeichen erlauben es, dass ein String über mehrere Zeilen geht    // und Anführungszeichen enthalten kann.   -``` +  val html = """<form id="daform">                  <p>Press belo', Joe</p>                  <input type="submit">                </form>""" -``` -# 2. Funktionen +   +///////////////////////////////////////////////// +// 2. Funktionen +/////////////////////////////////////////////////  // Funktionen werden so definiert    //   @@ -184,74 +190,74 @@ val html = """<form id="daform">  //    // Beachte: Es gibt kein return Schlüsselwort. In Scala ist der letzte Ausdruck    // in einer Funktion der Rückgabewert.   -``` +  def sumOfSquares(x: Int, y: Int): Int = {    val x2 = x * x    val y2 = y * y    x2 + y2  } -``` +  // Die geschweiften Klammern können weggelassen werden, wenn    // die Funktion nur aus einem einzigen Ausdruck besteht:   -``` +  def sumOfSquaresShort(x: Int, y: Int): Int = x * x + y * y -``` +  // Syntax für Funktionsaufrufe:   -``` +  sumOfSquares(3, 4)  // => 25 -``` +  // In den meisten Fällen (mit Ausnahme von rekursiven Funktionen), können    // Rückgabetypen auch weggelassen werden, da dieselbe Typ Inference, wie bei    // Variablen, auch bei Funktionen greift:   -``` +  def sq(x: Int) = x * x  // Compiler errät, dass der return type Int ist -``` +  // Funktionen können default parameter haben:   -``` +  def addWithDefault(x: Int, y: Int = 5) = x + y  addWithDefault(1, 2) // => 3  addWithDefault(1)    // => 6 -``` +  // Anonyme Funktionen sehen so aus:   -``` +  (x: Int) => x * x -``` +  // Im Gegensatz zu def bei normalen Funktionen, kann bei anonymen Funktionen     // sogar der Eingabetyp weggelassen werden, wenn der Kontext klar ist.    // Beachte den Typ "Int => Int", dies beschreibt eine Funktion,    // welche Int als Parameter erwartet und Int zurückgibt.   -``` +  val sq: Int => Int = x => x * x -``` +  // Anonyme Funktionen benutzt man ganz normal:   -``` +  sq(10)   // => 100 -``` +  // Wenn ein Parameter einer anonymen Funktion nur einmal verwendet wird,    // bietet Scala einen sehr kurzen Weg diesen Parameter zu benutzen,    // indem die Parameter als Unterstrich "_" in der Parameterreihenfolge    // verwendet werden. Diese anonymen Funktionen werden sehr häufig     // verwendet.   -``` +  val addOne: Int => Int = _ + 1    val weirdSum: (Int, Int) => Int = (_ * 2 + _ * 3)    addOne(5)      // => 6    weirdSum(2, 4) // => 16   -``` +  // Es gibt einen keyword return in Scala. Allerdings ist seine Verwendung    // nicht immer ratsam und kann fehlerbehaftet sein. "return" gibt nur aus    // dem innersten def, welches den return Ausdruck umgibt, zurück.    // "return" hat keinen Effekt in anonymen Funktionen:   -``` +  def foo(x: Int): Int = {      val anonFunc: Int => Int = { z =>        if (z > 5)   @@ -261,28 +267,30 @@ def foo(x: Int): Int = {    }      anonFunc(x)  // Zeile ist der return Wert von foo    }   -``` -# 3. Flow Control -## Wertebereiche und Schleifen -``` +///////////////////////////////////////////////// +// 3. Flow Control +///////////////////////////////////////////////// + +// Wertebereiche und Schleifen +  1 to 5  val r = 1 to 5  r.foreach(println)  r foreach println  (5 to 1 by -1) foreach (println) -```   -// Scala ist syntaktisch sehr grosszügig, Semikolons am Zeilenende   +   +// Scala ist syntaktisch sehr großzügig, Semikolons am Zeilenende    // sind optional, beim Aufruf von Methoden können die Punkte    // und Klammern entfallen und Operatoren sind im Grunde austauschbare Methoden    // while Schleife   -``` +  var i = 0  while (i < 10) { println("i " + i); i += 1 }  i    // i ausgeben, res3: Int = 10 -``` +  // Beachte: while ist eine Schleife im klassischen Sinne -    // Sie läuft sequentiell ab und verändert die loop-Variable.   @@ -291,28 +299,28 @@ i    // i ausgeben, res3: Int = 10  // und zu parellelisieren.  // Ein do while Schleife   -``` +  do {    println("x ist immer noch weniger wie 10")    x += 1  } while (x < 10) -``` +  // Endrekursionen sind ideomatisch um sich wiederholende    // Dinge in Scala zu lösen. Rekursive Funtionen benötigen explizit einen    // return Typ, der Compiler kann ihn nicht erraten.    // Unit, in diesem Beispiel.   -``` +  def showNumbersInRange(a: Int, b: Int): Unit = {    print(a)    if (a < b)      showNumbersInRange(a + 1, b)  }  showNumbersInRange(1, 14) -``` -## Conditionals -``` + +// Conditionals +  val x = 10  if (x == 1) println("yeah")  if (x == 10) println("yeah") @@ -320,186 +328,193 @@ if (x == 11) println("yeah")  if (x == 11) println ("yeah") else println("nay")  println(if (x == 10) "yeah" else "nope")  val text = if (x == 10) "yeah" else "nope" -``` -# 4. Daten Strukturen (Array, Map, Set, Tuples) -## Array -``` +///////////////////////////////////////////////// +// 4. Daten Strukturen (Array, Map, Set, Tuples) +///////////////////////////////////////////////// + +// Array +  val a = Array(1, 2, 3, 5, 8, 13)  a(0)  a(3)  a(21)    // Exception -``` -## Map - Speichert Key-Value-Paare -``` + +// Map - Speichert Key-Value-Paare +  val m = Map("fork" -> "tenedor", "spoon" -> "cuchara", "knife" -> "cuchillo")  m("fork")  m("spoon")  m("bottle")       // Exception  val safeM = m.withDefaultValue("no lo se")  safeM("bottle") -``` -## Set - Speichert Unikate, unsortiert (sortiert -> SortedSet) -``` + +// Set - Speichert Unikate, unsortiert (sortiert -> SortedSet) +  val s = Set(1, 3, 7)  s(0) //false  s(1) //true  val s = Set(1,1,3,3,7)  s: scala.collection.immutable.Set[Int] = Set(1, 3, 7) -``` -## Tuple - Speichert beliebige Daten und "verbindet" sie miteinander + +// Tuple - Speichert beliebige Daten und "verbindet" sie miteinander  // Ein Tuple ist keine Collection.   -``` +  (1, 2)  (4, 3, 2)  (1, 2, "three")  (a, 2, "three") -``` +  // Hier ist der Rückgabewert der Funktion ein Tuple    // Die Funktion gibt das Ergebnis, so wie den Rest zurück.   -``` +  val divideInts = (x: Int, y: Int) => (x / y, x % y)  divideInts(10, 3) -``` +  // Um die Elemente eines Tuples anzusprechen, benutzt man diese    // Notation: _._n wobei n der index des Elements ist (Index startet bei 1)   -``` +  val d = divideInts(10, 3)  d._1  d._2 -``` -# 5. Objekt Orientierte Programmierung -Bislang waren alle gezeigten Sprachelemente einfache Ausdrücke, welche zwar   -zum Ausprobieren und Lernen in der REPL gut geeignet sind, jedoch in   -einem Scala file selten alleine zu finden sind.   -Die einzigen Top-Level Konstrukte in Scala sind nämlich:   -- Klassen (classes) -- Objekte (objects) -- case classes -- traits +///////////////////////////////////////////////// +// 5. Objektorientierte Programmierung +///////////////////////////////////////////////// + +/* +  Bislang waren alle gezeigten Sprachelemente einfache Ausdrücke, welche zwar   +  zum Ausprobieren und Lernen in der REPL gut geeignet sind, jedoch in   +  einem Scala file selten alleine zu finden sind.   +  Die einzigen Top-Level Konstrukte in Scala sind nämlich:   + +  - Klassen (classes) +  - Objekte (objects) +  - case classes +  - traits -Diesen Sprachelemente wenden wir uns jetzt zu.   +  Diesen Sprachelemente wenden wir uns jetzt zu.   +*/ -## Klassen +// Klassen  // Zum Erstellen von Objekten benötigt man eine Klasse, wie in vielen    // anderen Sprachen auch.   // erzeugt Klasse mit default Konstruktor   -``` +  class Hund  scala> val t = new Hund  t: Hund = Hund@7103745 -``` +  // Der Konstruktor wird direkt hinter dem Klassennamen deklariert.   -``` +  class Hund(sorte: String)  scala> val t = new Hund("Dackel")  t: Hund = Hund@14be750c  scala> t.sorte //error: value sorte is not a member of Hund -``` +  // Per val wird aus dem Attribut ein unveränderliches Feld der Klasse    // Per var wird aus dem Attribut ein veränderliches Feld der Klasse   -``` +  class Hund(val sorte: String)  scala> val t = new Hund("Dackel")  t: Hund = Hund@74a85515  scala> t.sorte  res18: String = Dackel -``` +  // Methoden werden mit def geschrieben   -``` +  def bark = "Woof, woof!" -``` +  // Felder und Methoden können public, protected und private sein    // default ist public    // private ist nur innerhalb des deklarierten Bereichs sichtbar   -``` +  class Hund {    private def x = ...    def y = ...  } -``` +  // protected ist nur innerhalb des deklarierten und aller    // erbenden Bereiche sichtbar   -``` +  class Hund {    protected def x = ...  }  class Dackel extends Hund {    // x ist sichtbar  } -``` -##  Object -Wird ein Objekt ohne das Schlüsselwort "new" instanziert, wird das sog.   -"companion object" aufgerufen. Mit dem "object" Schlüsselwort wird so   -ein Objekt (Typ UND Singleton) erstellt. Damit kann man dann eine Klasse   -benutzen ohne ein Objekt instanziieren zu müssen.   -Ein gültiges companion Objekt einer Klasse ist es aber erst dann, wenn   -es genauso heisst und in derselben Datei wie die Klasse definiert wurde.   -``` + +// Object +// Wird ein Objekt ohne das Schlüsselwort "new" instanziert, wird das sog.   +// "companion object" aufgerufen. Mit dem "object" Schlüsselwort wird so   +// ein Objekt (Typ UND Singleton) erstellt. Damit kann man dann eine Klasse   +// benutzen ohne ein Objekt instanziieren zu müssen.   +// Ein gültiges companion Objekt einer Klasse ist es aber erst dann, wenn   +// es genauso heisst und in derselben Datei wie die Klasse definiert wurde.   +  object Hund {    def alleSorten = List("Pitbull", "Dackel", "Retriever")    def createHund(sorte: String) = new Hund(sorte)  } -``` -## Case classes -Fallklassen bzw. Case classes sind Klassen die normale Klassen um extra   -Funktionalität erweitern. Mit Case Klassen bekommt man ein paar   -Dinge einfach dazu, ohne sich darum kümmern zu müssen. Z.B.   -ein companion object mit den entsprechenden Methoden,   -Hilfsmethoden wie toString(), equals() und hashCode() und auch noch   -Getter für unsere Attribute (das Angeben von val entfällt dadurch)   -``` + +// Case classes +// Fallklassen bzw. Case classes sind Klassen die normale Klassen um extra   +// Funktionalität erweitern. Mit Case Klassen bekommt man ein paar   +// Dinge einfach dazu, ohne sich darum kümmern zu müssen. Z.B.   +// ein companion object mit den entsprechenden Methoden,   +// Hilfsmethoden wie toString(), equals() und hashCode() und auch noch   +// Getter für unsere Attribute (das Angeben von val entfällt dadurch)   +  class Person(val name: String)  class Hund(val sorte: String, val farbe: String, val halter: Person) -``` +  // Es genügt das Schlüsselwort case vor die Klasse zu schreiben.   -``` +  case class Person(name: String)  case class Hund(sorte: String, farbe: String, halter: Person) -``` +  // Für neue Instanzen brauch man kein "new"   -``` +  val dackel = Hund("dackel", "grau", Person("peter"))  val dogge = Hund("dogge", "grau", Person("peter")) -``` +  // getter   -``` +  dackel.halter  // => Person = Person(peter) -``` +  // equals   -``` +  dogge == dackel  // => false -``` +  // copy    // otherGeorge == Person("george", "9876")   -``` +  val otherGeorge = george.copy(phoneNumber = "9876") -``` -## Traits -Ähnlich wie Java interfaces, definiert man mit traits einen Objekttyp   -und Methodensignaturen. Scala erlaubt allerdings das teilweise   -implementieren dieser Methoden. Konstruktorparameter sind nicht erlaubt.   -Traits können von anderen Traits oder Klassen erben, aber nur von   -parameterlosen.   -``` + +// Traits +// Ähnlich wie Java interfaces, definiert man mit traits einen Objekttyp   +// und Methodensignaturen. Scala erlaubt allerdings das teilweise   +// implementieren dieser Methoden. Konstruktorparameter sind nicht erlaubt.   +// Traits können von anderen Traits oder Klassen erben, aber nur von   +// parameterlosen.   +  trait Hund {  	def sorte: String  	def farbe: String @@ -511,9 +526,9 @@ class Bernhardiner extends Hund{  	val farbe = "braun"  	def beissen = false  } -``` + -``` +  scala> b    res0: Bernhardiner = Bernhardiner@3e57cd70    scala> b.sorte   @@ -522,10 +537,10 @@ scala> b.bellen  res2: Boolean = true    scala> b.beissen    res3: Boolean = false   -``` +  // Traits können auch via Mixins (Schlüsselwort "with") eingebunden werden   -``` +  trait Bellen {  	def bellen: String = "Woof"  } @@ -541,25 +556,27 @@ scala> val b = new Bernhardiner  b: Bernhardiner = Bernhardiner@7b69c6ba  scala> b.bellen  res0: String = Woof -``` -# 6. Pattern Matching -Pattern matching in Scala ist ein sehr nützliches und wesentlich   -mächtigeres Feature als Vergleichsfunktionen in Java. In Scala   -benötigt ein case Statement kein "break", ein fall-through gibt es nicht.   -Mehrere Überprüfungen können mit einem Statement gemacht werden.   -Pattern matching wird mit dem Schlüsselwort "match" gemacht.   -``` +///////////////////////////////////////////////// +// 6. Pattern Matching +///////////////////////////////////////////////// + +// Pattern matching in Scala ist ein sehr nützliches und wesentlich   +// mächtigeres Feature als Vergleichsfunktionen in Java. In Scala   +// benötigt ein case Statement kein "break", ein fall-through gibt es nicht.   +// Mehrere Überprüfungen können mit einem Statement gemacht werden.   +// Pattern matching wird mit dem Schlüsselwort "match" gemacht.   +  val x = ...  x match {    case 2 =>    case 3 =>    case _ =>  } -``` +  // Pattern Matching kann auf beliebige Typen prüfen   -``` +  val any: Any = ...  val gleicht = any match {    case 2 | 3 | 5 => "Zahl" @@ -568,19 +585,19 @@ val gleicht = any match {    case 45.35 => "Double"    case _ => "Unbekannt"  } -``` +  // und auf Objektgleichheit   -``` +  def matchPerson(person: Person): String = person match {    case Person("George", nummer) => "George! Die Nummer ist " + number    case Person("Kate", nummer)   => "Kate! Die Nummer ist " + nummer    case Person(name, nummer)     => "Irgendjemand: " + name + ", Telefon: " + nummer  } -``` +  // Und viele mehr...   -``` +  val email = "(.*)@(.*)".r  // regex  def matchEverything(obj: Any): String = obj match {    // Werte: @@ -600,18 +617,21 @@ def matchEverything(obj: Any): String = obj match {    // Patterns kann man ineinander schachteln:    case List(List((1, 2, "YAY"))) => "Got a list of list of tuple"  } -``` +  // Jedes Objekt mit einer "unapply" Methode kann per Pattern geprüft werden    // Ganze Funktionen können Patterns sein   -``` +  val patternFunc: Person => String = {    case Person("George", number) => s"George's number: $number"    case Person(name, number) => s"Random person's number: $number"  } -``` -# 7. Higher-order functions + +///////////////////////////////////////////////// +// 37. Higher-order functions +///////////////////////////////////////////////// +  Scala erlaubt, das Methoden und Funktion wiederum Funtionen und Methoden    als Aufrufparameter oder Return Wert verwenden. Diese Methoden heissen    higher-order functions   @@ -621,116 +641,117 @@ Nennenswerte sind:  "filter", "map", "reduce", "foldLeft"/"foldRight", "exists", "forall"    ## List -``` +  def isGleichVier(a:Int) = a == 4  val list = List(1, 2, 3, 4)  val resultExists4 = list.exists(isEqualToFour) -``` +  ## map  // map nimmt eine Funktion und führt sie auf jedem Element aus und erzeugt    // eine neue Liste    // Funktion erwartet ein Int und returned ein Int   -``` +  val add10: Int => Int = _ + 10  -``` +  // add10 wird auf jedes Element angewendet   -``` +  List(1, 2, 3) map add10 // => List(11, 12, 13) -``` +  // Anonyme Funktionen können anstatt definierter Funktionen verwendet werden   -``` +  List(1, 2, 3) map (x => x + 10) -``` +  // Der Unterstrich wird anstelle eines Parameters einer anonymen Funktion    // verwendet. Er wird an die Variable gebunden.   -``` +  List(1, 2, 3) map (_ + 10) -``` +  // Wenn der anonyme Block und die Funtion beide EIN Argument erwarten,    // kann sogar der Unterstrich weggelassen werden.   -``` +  List("Dom", "Bob", "Natalia") foreach println -``` -## filter + +// filter  // filter nimmt ein Prädikat (eine Funktion von A -> Boolean) und findet    // alle Elemente die auf das Prädikat passen   -``` +  List(1, 2, 3) filter (_ > 2) // => List(3)  case class Person(name: String, age: Int)  List(    Person(name = "Dom", age = 23),    Person(name = "Bob", age = 30)  ).filter(_.age > 25) // List(Person("Bob", 30)) -``` -## reduce + +// reduce  // reduce nimmt zwei Elemente und kombiniert sie zu einem Element,    // und zwar solange bis nur noch ein Element da ist.   -## foreach +// foreach  // foreach gibt es für einige Collections   -``` +  val aListOfNumbers = List(1, 2, 3, 4, 10, 20, 100)  aListOfNumbers foreach (x => println(x))  aListOfNumbers foreach println -``` -## For comprehensions + +// For comprehensions  // Eine for-comprehension definiert eine Beziehung zwischen zwei Datensets.    // Dies ist keine for-Schleife.   -``` +  for { n <- s } yield sq(n)  val nSquared2 = for { n <- s } yield sq(n)  for { n <- nSquared2 if n < 10 } yield n  for { n <- s; nSquared = n * n if nSquared < 10} yield nSquared -``` +  ///////////////////////////////////////////////// -# 8. Implicits +// 8. Implicits  ///////////////////////////////////////////////// -**ACHTUNG:**   -Implicits sind ein sehr mächtiges Sprachfeature von Scala. Es sehr einfach   -sie falsch zu benutzen und Anfänger sollten sie mit Vorsicht oder am   -besten erst dann benutzen, wenn man versteht wie sie funktionieren.   -Dieses Tutorial enthält Implicits, da sie in Scala an jeder Stelle   -vorkommen und man auch mit einer Lib die Implicits benutzt nichts sinnvolles   -machen kann.   -Hier soll ein Grundverständnis geschaffen werden, wie sie funktionieren.   +// **ACHTUNG:**   +// Implicits sind ein sehr mächtiges Sprachfeature von Scala. +// Es sehr einfach   +// sie falsch zu benutzen und Anfänger sollten sie mit Vorsicht oder am   +// besten erst dann benutzen, wenn man versteht wie sie funktionieren.   +// Dieses Tutorial enthält Implicits, da sie in Scala an jeder Stelle   +// vorkommen und man auch mit einer Lib die Implicits benutzt nichts sinnvolles   +// machen kann.   +// Hier soll ein Grundverständnis geschaffen werden, wie sie funktionieren.    // Mit dem Schlüsselwort implicit können Methoden, Werte, Funktion, Objekte    // zu "implicit Methods" werden.   -``` +  implicit val myImplicitInt = 100  implicit def myImplicitFunction(sorte: String) = new Hund("Golden " + sorte) -``` +  // implicit ändert nicht das Verhalten eines Wertes oder einer Funktion   -``` +  myImplicitInt + 2                   // => 102  myImplicitFunction("Pitbull").sorte // => "Golden Pitbull" -``` +  // Der Unterschied ist, dass diese Werte ausgewählt werden können, wenn ein    // anderer Codeteil einen implicit Wert benötigt, zum Beispiel innerhalb von    // implicit Funktionsparametern    // Diese Funktion hat zwei Parameter: einen normalen und einen implicit   -``` +  def sendGreetings(toWhom: String)(implicit howMany: Int) =    s"Hello $toWhom, $howMany blessings to you and yours!" -``` +  // Werden beide Parameter gefüllt, verhält sich die Funktion wie erwartet   -``` +  sendGreetings("John")(1000)  // => "Hello John, 1000 blessings to you and yours!" -``` +  // Wird der implicit Parameter jedoch weggelassen, wird ein anderer    // implicit Wert vom gleichen Typ genommen. Der Compiler sucht im   @@ -739,66 +760,69 @@ sendGreetings("John")(1000)  // => "Hello John, 1000 blessings to you and yours!  // geforderten Typ konvertieren kann.    // Hier also: "myImplicitInt", da ein Int gesucht wird   -``` +  sendGreetings("Jane")  // => "Hello Jane, 100 blessings to you and yours!" -``` +  // bzw. "myImplicitFunction"    // Der String wird erst mit Hilfe der Funktion in Hund konvertiert, und    // dann wird die Methode aufgerufen   -``` +  "Retriever".sorte // => "Golden Retriever" -``` -# 9. Misc -## Importe -``` + +///////////////////////////////////////////////// +// 19. Misc +///////////////////////////////////////////////// +// Importe +  import scala.collection.immutable.List -``` +  // Importiere alle Unterpackages   -``` +  import scala.collection.immutable._ -``` +  // Importiere verschiedene Klassen mit einem Statement   -``` +  import scala.collection.immutable.{List, Map} -``` +  // Einen Import kann man mit '=>' umbenennen   -``` +  import scala.collection.immutable.{List => ImmutableList} -``` +  // Importiere alle Klasses, mit Ausnahem von....    // Hier ohne: Map and Set:   -``` +  import scala.collection.immutable.{Map => _, Set => _, _} -``` -## Main  -``` + +// Main  +  object Application {    def main(args: Array[String]): Unit = { -    // stuff goes here. +    // Sachen kommen hierhin    }  } -``` -## I/O + +// I/O  // Eine Datei Zeile für Zeile lesen   -``` +  import scala.io.Source  for(line <- Source.fromFile("myfile.txt").getLines())    println(line) -``` +  // Eine Datei schreiben   -``` +  val writer = new PrintWriter("myfile.txt")  writer.write("Schreibe Zeile" + util.Properties.lineSeparator)  writer.write("Und noch eine Zeile" + util.Properties.lineSeparator)  writer.close() +  ```  ## Weiterführende Hinweise  diff --git a/de-de/yaml-de.html.markdown b/de-de/yaml-de.html.markdown index 19ea9e87..a46c30f6 100644 --- a/de-de/yaml-de.html.markdown +++ b/de-de/yaml-de.html.markdown @@ -30,7 +30,7 @@ null_Wert: null  Schlüssel mit Leerzeichen: value  # Strings müssen nicht immer mit Anführungszeichen umgeben sein, können aber:  jedoch: "Ein String in Anführungzeichen" -"Ein Schlüssel in Anführungszeichen": "Nützlich, wenn du einen Doppelpunkt im Schluessel haben willst." +"Ein Schlüssel in Anführungszeichen": "Nützlich, wenn du einen Doppelpunkt im Schlüssel haben willst."  # Mehrzeilige Strings schreibst du am besten als 'literal block' (| gefolgt vom Text)  # oder ein 'folded block' (> gefolgt vom text). @@ -64,7 +64,7 @@ eine_verschachtelte_map:          hallo: hallo  # Schlüssel müssen nicht immer String sein. -0.25: ein Float-Wert als Schluessel +0.25: ein Float-Wert als Schlüssel  # Schlüssel können auch mehrzeilig sein, ? symbolisiert den Anfang des Schlüssels  ? |  | 
