1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
|
---
language: rust
contributors:
- ["P1start", "http://p1start.github.io/"]
translators:
- ["Christian Albrecht", "https://github.com/coastalchief"]
lang: de-de
filename: lernerust-de.rs
---
Rust ist eine Programmiersprache von Mozilla Research.
Rust vereint Sicherheit, Nebenläufigkeit und eine hohe Praxistauglichkeit.
Sicherheit bedeuted, dass Programmierfehler ausgeschlossen werden, die zu
Speicherzugriffsfehlern führen könnten. Das funktioniert u.a. dadurch, dass
es keinen Garbage Collector gibt, sondern ein besonderes Typsystem.
Das erste Release von Rust, 0.1, wurde im Januar 2012 veröffentlicht.
In den nächsten drei Jahren wurde die Sprache so schnell und aktiv weiter-
entwickelt, dass es einfach keine stabile gab und geraten wurde den
nightly build zu nutzen.
Am 15. Mai 2015 wurde Rust 1.0 freigegeben, und zwar mit der Garantie einer
Abwärtskompatabilität. Verbesserungen der Kompilierzeit und andere Compiler
verbesserungen finden im Moment im nightly build statt. Von Rust gibt es im
Moment ungefähr alle sechs Wochen ein Release. Rust 1.1 beta wurde zusammen
mit dem 1.0 Release zur Verfügung gestellt.
Obwohl Rust eine ziemlich low-level Sprache ist, vereint sie Ansätze aus
der Welt der funktionalen, der objektorientierten und der nebenläufigen
Programmierung. Dadurch kann in Rust nicht nur schnell, sondern auch sehr
effizient entwickelt werden.
```rust
// Dies ist ein Kommentar. Ein einzeiliger...
/* ...und multi-zeilen Kommentare sehe so aus */
/////////////////////
// 0. Installation //
/////////////////////
// Stabile binaries gibt es unter https://www.rust-lang.org/downloads.html
// Programme werden in .rs Dateien geschrieben also zum Beispiel
// "main.rs" und dann kompiliert "rustc main.rs"
// Herauskommt eine ausführbare Datei "main"
// Für dieses Tutorial reicht das vollkommen aus. Für größere Projekte
// sollte das unten beschriebene Cargo angeschaut werden.
// Cargo
// Ein gängiges Tool um Rust Projekte zu verwalten ist Cargo. Es macht im
// wesentlichen drei Dinge: Code bauen, Dependencies laden und
// Dependencies bauen.
// Um ein vorhandenes Projekt zu cargo-ifyen müssen drei Dinge gemacht werden
// * Erstelle eine Cargo.toml Konfigurationsdatei
// * Verschiebe Source Code in ein src Verzeichnis
// * Lösche das alte Executable
//
// 'cargo build' baut den Code
// 'cargo run' baut und führt das Programm aus
///////////////
// 1. Basics //
///////////////
// Funktionen
// `i32` ist der Typ für einen 32-bit signed Integer
fn add2(x: i32, y: i32) -> i32 {
// Impliziter return (kein Semikolon)
x + y
}
// Main Funktion
fn main() {
// Zahlen //
// Unveränderliche Variable
let x: i32 = 1;
// Integer/float Suffixe
let y: i32 = 13i32;
let f: f64 = 1.3f64;
// Type inference
Meistens kann der Rust Compiler selbst schlussfolgern, von welchem
Typ eine Variable ist, so dass man den Typ nicht explizit angeben muss.
In diesem Tutorial werden Typen explizit angegeben, um zu demonstrieren,
welche Möglichkeiten es gibt. Wenn man damit vertraut ist, kann man die
Typen auch weglassen und die Type Inference hilft dann im Hintergrund.
let implicit_x = 1;
let implicit_f = 1.3;
// Arithmetik
let sum = x + y + 13;
// Veränderliche Variable
let mut mutable = 1;
mutable = 4;
mutable += 2;
// Strings //
// Strings gibt es in zwei Typen: &str und String
// Zunächst &str
let x: &str = "hello world!";
// Ausgabe
println!("{} {}", f, x); // 1.3 hello world
// Ein `String` – heap-allokierter String
let s: String = "hello world".to_string();
// Ein string slice – ist eigentlich ein unveränderlicher Pointer
// auf einen String – er enthält nicht den Inhalt den String, sondern
// eben nur den Pointer auf etwas, dass den Inhalt kennt:
// (In diesem Fall, `s`)
let s_slice: &str = &s;
// Ausgabe
println!("{} {}", s, s_slice); // hello world hello world
// Vektoren/Arrays //
// Ein Array mit fester Größe
let vier_ints: [i32; 4] = [1, 2, 3, 4];
// Ein dynamisches Array (Vektorentor)
let mut vector: Vec<i32> = vec![1, 2, 3, 4];
vector.push(5);
// Ein slice – eine unveränderliche Ansicht, oder Pointer auf einen
// Vektor oder ein Array. Wie bei Strings, nur eben bei Vektoren
let slice: &[i32] = &vector;
// Benutze `{:?}` um eine debug Ausgabe zu erzeugen
println!("{:?} {:?}", vector, slice); // [1, 2, 3, 4, 5] [1, 2, 3, 4, 5]
// Tuples //
// Ein Tuple ist eine Liste mit fester Größe und kann Werte
// von unterschiedlichen Typen enthalten
let x: (i32, &str, f64) = (1, "hello", 3.4);
// Werte aus Vektor mit `let` destrukturieren
let (a, b, c) = x;
println!("{} {} {}", a, b, c); // 1 hello 3.4
// Vektor Indizes
println!("{}", x.1); // hello
//////////////
// 2. Typen //
//////////////
// Struct
struct Punkt {
x: i32,
y: i32,
}
let anfang: Punkt = Punkt { x: 0, y: 0 };
// Ein struct mit unbenannten Felder heisst ‘tuple struct’
struct Punkt2(i32, i32);
let anfang2 = Punkt2(0, 0);
// Einfache enum, so ähnlich wie in C
enum Richtung {
Links,
Rechts,
Hoch,
Runter,
}
let hoch = Richtung::Hoch;
// Enum mit Feldern
enum OptionalI32 {
EinI32(i32),
Nix,
}
let zwei: OptionalI32 = OptionalI32::EinI32(2);
let nix = OptionalI32::Nix;
// Generics //
struct Foo<T> { bar: T }
// In der Standard Bibliothek heisst das hier `Option`
enum Optional<T> {
EinWert(T),
KeinWert,
}
// Methoden //
impl<T> Foo<T> {
// Methoden erwarten einen `self` Parameter
fn get_bar(self) -> T {
self.bar
}
}
let a_foo = Foo { bar: 1 };
println!("{}", a_foo.get_bar()); // 1
// Traits (vergleichbar mit Interfaces oder Typklassen in anderen Sprachen)
// In Traits werden nur Method Signaturen erstellt.
// Die Implementierung findet im impl statt.
trait MacheIrgendwas<T> {
fn macheIrgendwas(self) -> Option<T>;
}
impl<T> MacheIrgendwas<T> for Foo<T> {
fn macheIrgendwas(self) -> Option<T> {
mache(self.bar)
}
}
let anderes_foo = Foo { bar: 1 };
println!("{:?}", anderes_foo.macheIrgendwas()); // mache(1)
/////////////////////////
// 3. Pattern matching //
/////////////////////////
let foo = OptionalI32::AnI32(1);
match foo {
OptionalI32::EinI32(n) => println!("hier ist ein i32: {}", n),
OptionalI32::Nix => println!("hier ist nix!"),
}
// Advanced pattern matching
struct FooBar { x: i32, y: OptionalI32 }
let bar = FooBar { x: 15, y: OptionalI32::EinI32(32) };
match bar {
FooBar { x: 0, y: OptionalI32::EinI32(0) } =>
println!("Beide Zahlen sind 0!"),
FooBar { x: n, y: OptionalI32::EinI32(m) } if n == m =>
println!("Beide Zahlen sind gleich"),
FooBar { x: n, y: OptionalI32::EinI32(m) } =>
println!("Zahlen sind unterschiedlich: {} {}", n, m),
FooBar { x: _, y: OptionalI32::Nix } =>
println!("Die zweite Zahl ist leer!"),
}
/////////////////////
// 4. Control //
/////////////////////
// `for` Schleife/Iterationen
let array = [1, 2, 3];
for i in array.iter() {
println!("{}", i);
}
// Ranges
for i in 0u32..10 {
print!("{} ", i);
}
println!("");
// gibt aus: `0 1 2 3 4 5 6 7 8 9 `
// `if`
if 1 == 1 {
println!("Mathe ist klappt!");
} else {
println!("Oh nein...");
}
// `if` als Ausdruck
let wert = if true {
"gut"
} else {
"schlecht"
};
// `while` Schleife
while 1 == 1 {
println!("Läuft...");
}
// Unendliche Schleifen
loop {
println!("Hello!");
}
/////////////////////////////////////
// 5. Speichersicherheit & Pointer //
/////////////////////////////////////
// Owned pointer – nur eine Sache kann einen Pointer 'besitzen'.
// Das heisst, wenn das Objekt `Box` seinen scope verlässt oder verliert,
// wird es automatisch im Speicher de-allokiert.
let mut mine: Box<i32> = Box::new(3);
// Jetzt wird die Box dereferenziert
*mine = 5;
// Jetzt geht `mine` in den Besitz von `now_its_mine` über.
// `mine` wird verschoben.
let mut now_its_mine = mine;
*now_its_mine += 2;
println!("{}", now_its_mine); // ergibt 7
// Das würde nicht kompilieren, da `now_its_mine` jetzt den Pointer besitzt
// println!("{}", mine);
// Reference – ein unveränderlicher Pointer der fremde Daten referenziert
// Wenn eine Referenz auf einen Wert gesetzt wird, heisst das, dass man den
// Wert ausleiht (‘borrowed’).
// Ein ausgeliehener Wert ist unveränderlich und lebt solange wie der
// Scope existiert, in dem er erstellt wurde.
let mut var = 4;
var = 3;
let ref_var: &i32 = &var;
println!("{}", var); // Anders als `box`, `var` kann hier weiter verwendet werden
println!("{}", *ref_var);
// var = 5; // das kompiliert nicht, da `var` ausgeliehen ist
// *ref_var = 6; // das kompiliert auch nicht, da `ref_var` eine unveränderliche Referenz ist
// Veränderliche Referenzen
// Solange ein Wert veränderlich geliehen wurde, kann man nicht darauf zugreifen
let mut var2 = 4;
let ref_var2: &mut i32 = &mut var2;
*ref_var2 += 2; // '*' wird benutzt um auf den veränderlich geliehenen Wert var2 zu zeigen
println!("{}", *ref_var2); // 6 , //var2 würde nicht kompilieren. //ref_var2 ist vom Typ &mut i32, also //stores a reference to an i32 not the value.
// var2 = 2; // würde das nicht kompilieren, da `var2` geliehen wurde.
}
```
## Weitere Informationen
Es gibt eine ganze Reihe mehr über Rust zu sagen. Dieser Text gibt nur einen
Einblick in die wichtigsten Sprachmerkmale.
Um mehr über Rust zu erfahren, sollte man mit den folgenden Stellen starten:
1. Englisch:
* [Die offizielle Rust Webseite](http://rust-lang.org)
* [The Rust Programming Language](https://doc.rust-lang.org/stable/book/README.html)
* [/r/rust](http://reddit.com/r/rust)
* the #rust channel on irc.mozilla.org
2. Deutsch
* [Rust Wikipedia](https://de.wikipedia.org/wiki/Rust_(Programmiersprache))
* [Artikel im LinuxMagazin](http://www.linux-magazin.de/Ausgaben/2015/08/Rust)
|