Skip to content

Commit

Permalink
fix whitespace issues -1
Browse files Browse the repository at this point in the history
  • Loading branch information
WebFreak001 committed Jun 3, 2022
1 parent 4fbcacd commit 27ad79b
Show file tree
Hide file tree
Showing 31 changed files with 299 additions and 293 deletions.
10 changes: 8 additions & 2 deletions .github/workflows/d.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,15 @@ jobs:
- name: 'Run sanitycheck'
run: |
echo "Check for trailing whitespace"
grep -nr --include \*.md '\s$' . ; test $? -eq 1
if [ grep -nr --include \*.md '\s$' . ];
echo "Found trailing whitespace, please remove"
exit 1
fi
echo "Check for tabs"
grep -nrP --include \*.md '\t' . ; test $? -eq 1
if [ grep -nrP --include \*.md '\t' . ];
echo "Found tabs, please replace with spaces"
exit 1
fi
git clone https://github.com/dlang-tour/core ../tour
mkdir -p ../tour/public/content/lang
mv * ../tour/public/content/lang
Expand Down
42 changes: 21 additions & 21 deletions basics/alias-strings.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
# Alias & Strings

Nun, da uns Arrays bekannt sind und wir mit den Basis-Typen
Nun, da uns Arrays bekannt sind und wir mit den Basis-Typen
und dem Schlüsselwort`immutable` beschäftigt haben, wird es
Zeit zwei neue Konstrukte in einer Zeile einzuführen:

alias string = immutable(char)[];
Der Begriff `string` wird durch das Schlüsselwort `alias` definiert,

Der Begriff `string` wird durch das Schlüsselwort `alias` definiert,
und zwar als Slice bestehend aus `immutable(char)`s.
Das bedeutet, sobald ein `string` konstruiert wurde, wird sich sein
Das bedeutet, sobald ein `string` konstruiert wurde, wird sich sein
Inhalt nie mehr ändern. Und damit sind wir bei dem zweiten Konstrukt:
Willkommen UTF-8 `string`!

Aufgrund ihrer Unveränderlichkeit (engl.: immutablility) können
`string`s über verschiedene Threads hinweg geteilt werden. Da `string`
Aufgrund ihrer Unveränderlichkeit (engl.: immutablility) können
`string`s über verschiedene Threads hinweg geteilt werden. Da `string`
ein Slice ist, können Teile ohne Speicher-Allokationen entnommnen werden.
Die Standard-Funktion `std.algorithm.splitter`](https://dlang.org/phobos/std_algorithm_iteration.html#.splitter)
z.B. teilt einen String anhand von Zeilensprüngen (newline-Zeichen)
Die Standard-Funktion `std.algorithm.splitter`](https://dlang.org/phobos/std_algorithm_iteration.html#.splitter)
z.B. teilt einen String anhand von Zeilensprüngen (newline-Zeichen)
ohne jede Speicher-Allokation.

Neben dem UTF-8 `string` gibt es zwei weitere Typen:

alias wstring = immutable(wchar)[]; // UTF-16
alias dstring = immutable(dchar)[]; // UTF-32

Diese Varianten können durch Nutzung der `to`-Methode aus `std.conv`
Diese Varianten können durch Nutzung der `to`-Methode aus `std.conv`
einfach ineinander konvertiert werden:

dstring myDstring = to!dstring(myString);
Expand All @@ -33,10 +33,10 @@ einfach ineinander konvertiert werden:
### Unicode Strings

Ein einfacher `string` ist als ein Array aus 8-bit Unicode [code
units](http://unicode.org/glossary/#code_unit) definiert. Alle Array-Operationen
können auf Strings angewandt werden, aber dies wird nur auf der Code-Unit-Ebene
units](http://unicode.org/glossary/#code_unit) definiert. Alle Array-Operationen
können auf Strings angewandt werden, aber dies wird nur auf der Code-Unit-Ebene
funktionieren, nicht aber auf Zeichen-Ebene! Gleichzeitig interpretieren die
Algorithmen der Standard-Bibliothek Strings als Sequenzen aus
Algorithmen der Standard-Bibliothek Strings als Sequenzen aus
[Code Points](http://unicode.org/glossary/#code_point). Darüber hinaus gibt es
die Option der Behandlung der Sequenz als
[Grapheme](http://unicode.org/glossary/#grapheme) durch explizite Nutznung von
Expand All @@ -56,22 +56,22 @@ Diese kleine Beispiel verdeutlicht die unterschiedlichen Interpretationen:

Hier ist die tatsächliche Länge des Arrays `s` 3, weil es 3 Code Units
enthält: `0x41`, `0x03` and `0x08`. Von diesen definieren zwei einen einzelnen
Code Point (kombinierende diakritische Zeichen) und
Code Point (kombinierende diakritische Zeichen) und
[`walkLength`](https://dlang.org/library/std/range/primitives/walk_length.html)
(Funktion der Standard-Bibliothek zur Berechnung der Länge beliebiger Ranges)
zählt zwei Code Points. Schließlich ermittelt `byGrapheme` in einer aufwändigeren
Berechnung, dass sich diese beiden Code Points zu einem einzigen angezeigten
Berechnung, dass sich diese beiden Code Points zu einem einzigen angezeigten
Zeichen zusammensetzen.
Korrekte Unicode-Verarbeitung kann sehr kompliziert sein. Trotzdem dürfen
Korrekte Unicode-Verarbeitung kann sehr kompliziert sein. Trotzdem dürfen
D-Entwickler String-Variablen als magische Byte-Arrays betrachten und sich darauf
verlassen, dass die Standard-Bibliothek "das Richtige tut".
Die meiste Unicode-Funktionalität wird in dem Modul
verlassen, dass die Standard-Bibliothek "das Richtige tut".
Die meiste Unicode-Funktionalität wird in dem Modul
[`std.uni`](https://dlang.org/library/std/uni.html) bereitgestellt, Grundlegenderes
in [`std.utf`](https://dlang.org/library/std/utf.html).

### Mehrzeilige Strings

Für die Erzeugung mehrzeiliger Strings bietet sich die
Für die Erzeugung mehrzeiliger Strings bietet sich die
`string str = q{ ... }`-Syntax an:

string multiline = q{ This
Expand All @@ -83,7 +83,7 @@ Für die Erzeugung mehrzeiliger Strings bietet sich die

Auch ist es möglich Raw Strings zu benutzen, um die aufwändige Verarbeitung
von reservierten Symbolen zu minimieren. Raw Strings können mittels Backticks
(invertierte Hochkommanta) (`` ` ... ` ``) oder den r(aw)-Präfix (`r" ... "`)
(invertierte Hochkommanta) (`` ` ... ` ``) oder den r(aw)-Präfix (`r" ... "`)
deklariert werden.

string raw = `raw "string"`; // raw "string"
Expand All @@ -107,7 +107,7 @@ import std.string: format;
void main() {
// format generiert einen String mittels
// printf-artiger Syntax. D erlaubt
// printf-artiger Syntax. D erlaubt
// native UTF-String-Verarbeitung!
string str = format("%s %s", "Hellö",
"Wörld");
Expand All @@ -120,7 +120,7 @@ void main() {
~ " of string: ",
str.byGrapheme.walkLength);
// Strings sind einfache Arrays!
// Strings sind einfache Arrays!
// Somit funktionieren alle Array-
// Operation auch mit Strings!
import std.array: replace;
Expand Down
22 changes: 11 additions & 11 deletions basics/associative-arrays.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Assoziative Arrays

D besitzt integrierte *Assoziative Arrays* (auch als Hashtabelle
oder Hashmap bekannt). Ein Assoziatives Array mit ein Schlüssel
des Typs `string` und einem Wert des Typs `int` wird folgendermaßen
D besitzt integrierte *Assoziative Arrays* (auch als Hashtabelle
oder Hashmap bekannt). Ein Assoziatives Array mit ein Schlüssel
des Typs `string` und einem Wert des Typs `int` wird folgendermaßen
erzeugt:

int[string] arr;
Expand All @@ -17,22 +17,22 @@ ist, kann der `in`-Ausdruck genutzt werden:
if ("key1" in arr)
writeln("Yes");

Der `in`-Ausdruck gibt einen Zeiger auf den Wert zurück, falls er
Der `in`-Ausdruck gibt einen Zeiger auf den Wert zurück, falls er
gefunden wurde, anderenfalls einen `null`-Zeiger. Also können
Existenz-Test und Schreiben komfortabel kombiniert werden:

if (auto val = "key1" in arr)
*val = 20;

Zugriff auf einen nicht existierenden Schlüssel führt zu einem
`RangeError` und dem sofortigen Abbruch der Anwendung. Für
Zugriff auf einen nicht existierenden Schlüssel führt zu einem
`RangeError` und dem sofortigen Abbruch der Anwendung. Für
sicheren Zugriff mit einen Standardwert (engl: default value)
gibt es `get(key, defaultValue)`.

Assoziativery Arrays bieten neben der `.length`-Eigenschaft
herkömmlicher Arrays auch `.remove(val)`, um Einträge über
ihren Schlüssel zu entfernen.
Dem Leser wird als Übung empfohlen, die speziellen `.byKey`-
herkömmlicher Arrays auch `.remove(val)`, um Einträge über
ihren Schlüssel zu entfernen.
Dem Leser wird als Übung empfohlen, die speziellen `.byKey`-
und `.byValue`-Ranges zu erforschen.

### Weiterführende Quellen
Expand Down Expand Up @@ -61,13 +61,13 @@ int[string] wordCount(string text)
import std.algorithm.iteration : splitter;
import std.string : toLower;
// Durch Wörter indiziert und Anzahl
// Durch Wörter indiziert und Anzahl
// zurückgebend
int[string] words;
foreach(word; splitter(text.toLower(), " "))
{
// Inkrementiere Wortzähler
// Inkrementiere Wortzähler
// falls ein Wort gefunden wurde.
// Integer-Standartwert ist 0.
words[word]++;
Expand Down
22 changes: 11 additions & 11 deletions basics/classes.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ In D werden Klassen generell mit `new` auf dem Heap instanziiert:

auto bar = new Bar;

Klassenobjekte sind immer Referenztypen. Anders als `struct`s,
Klassenobjekte sind immer Referenztypen. Anders als `struct`s,
die beim Aufruf kopiert werden (engl: call by value), werden Objekte
nur als Referenz weitergereicht (engl.: call by reference).

Expand All @@ -24,7 +24,7 @@ freigegeben wird, sobald keine Referenzen mehr auf das Objekt existieren.
### Vererbung

Wenn eine Memberfunktion einer Basisklasse überschrieben wird, muss das
Schlüsselwort `override` benutzt werden, um dies anzuzeigen. So wird
Schlüsselwort `override` benutzt werden, um dies anzuzeigen. So wird
ungewolltes Überschreiben von Funktionen vermieden.

class Bar: Foo {
Expand All @@ -35,20 +35,20 @@ In D können Klassen nur von Klassen erben.

### Final und abstract Memberfunktionen

- Eine Funktion kann als `final` markiert werden, um das Überschreiben
- Eine Funktion kann als `final` markiert werden, um das Überschreiben
zu verbieten
- Eine Funktion kann als `abstract` markiert werden, um das Überschreiben
- Eine Funktion kann als `abstract` markiert werden, um das Überschreiben
zu erzwingen
- Eine ganze Klasse kann als `abstract` deklariert werden, um sicherzustellen,
dass sie nicht instanziiert wird
- `super(..)` dient zum expliziten Aufruf des Basiskonstruktors

### Prüfen der Identität

Der Inhalt von Klassenobjekten wird mithilfe der Operatoren `==` and `!=`
Der Inhalt von Klassenobjekten wird mithilfe der Operatoren `==` and `!=`
verglichen. Daher ist der Vergleich gegen `null` nicht zulässig, da `null`
keinen Inhalt besitzt.
Das `is` vergleicht die Identität von Objekten. Um auf Nicht-Identität zu prüfen,
Das `is` vergleicht die Identität von Objekten. Um auf Nicht-Identität zu prüfen,
sollte `e1 !is e2` verwendet werden.

```d
Expand All @@ -75,7 +75,7 @@ ist Identität gleichwertig mit Gleichheit.
import std.stdio : writeln;
/*
Ausgefallener Typ der für alles genutzt
Ausgefallener Typ der für alles genutzt
werden kann...
*/
class Any {
Expand All @@ -92,7 +92,7 @@ class Any {
return type;
}
// Diese Fuktion muss
// Diese Fuktion muss
// implementiert werden!
abstract string convertToString();
}
Expand All @@ -111,12 +111,12 @@ class Integer: Any {
this.number = number;
}
// Dies ist implizit.
// Dies ist implizit.
public:
override string convertToString() {
import std.conv : to;
// Das Schweizer-Taschenmesser
// Das Schweizer-Taschenmesser
// der Konvertierung...
return to!string(number);
}
Expand Down Expand Up @@ -145,7 +145,7 @@ void main()
];
foreach (any; anys) {
writeln("Typ von any = ",
writeln("Typ von any = ",
any.getType());
writeln("Inhalt = ",
any.convertToString());
Expand Down
22 changes: 11 additions & 11 deletions basics/delegates.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Eine Funktion kann auch Parameter einer Funktion sein:
doSomething(add); // use global function `add` here
// add must have 2 int parameters

`doer` kann wie jede andere normale Funktion aufgerufen
`doer` kann wie jede andere normale Funktion aufgerufen
werden.

### Lokale Funktionen mit Kontext
Expand All @@ -22,11 +22,11 @@ ein Zeiger auf eine globale Funktion. Sobald auf eine Memberfunktion
oder eine lokale Funktion verwiesen wird, muss ein `delegate`
verwendet werden. Das ist ein Funktionszeiger mit zusätzlichen
Informationen zu seinem Kontext (in anderen Programmiersprachen
auch **Closure** genannt). Ein auf eine Memberfunktion einer
auch **Closure** genannt). Ein auf eine Memberfunktion einer
Klasse zeigendes `delegate` enthält z.B. einen Zeiger auf das
Klassenobjekt. Ein `delegate`, erzeugt in einer verschachtelten
Funktion, enthält stattdessen einen Link zu seinem umgebenden
Kontext. Allerdings darf der D-Compiler automatisch eine Kopie
Funktion, enthält stattdessen einen Link zu seinem umgebenden
Kontext. Allerdings darf der D-Compiler automatisch eine Kopie
des Kontextes auf dem Heap erstellen, falls dies der Speicher-
sicherheit dient. Das Delegate enthält dann einen Link zu diesem
Heap-Bereich
Expand All @@ -43,31 +43,31 @@ würde so aussehen:

void doSomething(int delegate(int,int) doer);

`delegate`- und `function`-Objekte können nicht gemischt werden.
`delegate`- und `function`-Objekte können nicht gemischt werden.
Daher konvertiert die Standardfunktion
[`std.functional.toDelegate`](https://dlang.org/phobos/std_functional.html#.toDelegate)
eine `function` in ein `delegate`.

### Anonyme Funktionen und Lambdafunktionen

Da Funktionen als Variablen gespeichert und an andere Funktionen
Da Funktionen als Variablen gespeichert und an andere Funktionen
übergeben werden können, ist es mühsam, sie zu definieren und ihnen
einen Namen zu geben. Daher erlaubt D namenlose Funktionen und
einen Namen zu geben. Daher erlaubt D namenlose Funktionen und
einzeilige _Lambdafunktionen_.

auto f = (int lhs, int rhs) {
return lhs + rhs;
};
// Lambdafunktion, gleich mit obiger Funktion
auto f = (int lhs, int rhs) => lhs + rhs;
auto f = (int lhs, int rhs) => lhs + rhs;

Auch besteht die Möglichkeit, Strings als Template-Argumente an
funktionale Teile der D-Standardbibliothek zu nutzen. Dies erlaubt
z.B. eine komfortable Art der Definition einer Reduce-Funktion:

[1, 2, 3].reduce!`a + b`; // 6

String-Funktionen sind nur möglich für _ein oder zwei_ Argumente,
String-Funktionen sind nur möglich für _ein oder zwei_ Argumente,
wobei `a` als erstes und `b` als zweites Argument dient.

### Weiterführende Quellen
Expand All @@ -78,7 +78,7 @@ wobei `a` als erstes und `b` als zweites Argument dient.

```d
import std.stdio : writeln;
enum IntOps {
add = 0,
sub = 1,
Expand All @@ -90,7 +90,7 @@ enum IntOps {
Stellt eine math. Berechnung bereit
Params:
op = gewählte math. Operation
Returns: delegate, welches die math.
Returns: delegate, welches die math.
Operation ausführt
*/
auto getMathOperation(IntOps op)
Expand Down
Loading

0 comments on commit 27ad79b

Please sign in to comment.