Rust 🦀

Rust 🦀

»Eine Sprache die jeden dazu bewegt zuverlässige und effiziente Software zu schreiben.«

Übersicht

  1. Kurzgeschichte & Enterprise 🏢
  2. Sprachkonzepte 👾🛟
  3. Java♨️/🦀Rust (tradeoffs)
  4. 🦀 WASM 🕸️ Demo

Kurzgeschichte
& Enterprise 🏢

Rust Historie

						%%{init: {'theme': 'dark', 'themeVariables': { 'darkMode': false }}}%%
						timeline
							2009 : Mozilla subventioniert zuvor privates Projekt von Graydon Hoare zum ersten Mal. 
							2010 : Rust wird von Mozilla offiziell angekündigt.
							2011 : `rustc` kompiliert sich erstmals selbst.
							2015 : Rust 1.0 ✅
							2020 : Rusts Typsicherheit wird durch Ralf Jung formal bewiesen.
							2021 : AWS, Google, Huawei, Microsoft, Mozilla und Rust-Team gründen die `Rust Foundation`
							November 2023: Stable Rust auf v1.74.0
						
Wo kommt Rust nun genau her?

Der ursprüngliche Rust Compiler ist in Objective Caml geschrieben worden.
Da OCaml🐫 selbst eine Meta-Language (ML) ist,
wird Rust die Einordnung als funktionale Programmiersprache vererbt.*

Funfact: OCaml🐫 hatte seinen ersten Release im Jahr 1996, wie Java♨️.

Unterschiede?

🐫 ≠ 🦀

OCaml ist interpretiert, Rust ist über LLVM 🐉 kompiliert.
OCaml ist dynamisch typisiert, Rust ist statisch typisiert (& Typ-inferiert).
*OCaml ist pure funktional, Rust ist multiparadigmatisch mit funktionaler Ausrichtung.
OCaml ist eine Meta-Language, Rust ist eine Systemsprache.

Ist Rust Enterprise rdy?

Fragen wir Tech-Unternehmen..

  • Mozilla
  • Linux
  • Google
  • Microsoft
  • Cloudflare
  • & Co.

Ist Rust Enterprise rdy?

Das sagen Tech-Unternehmen..

Wozu ist Rust geeignet?

Als Allzweck-Programmiersprache..

Eben alle Ziele und Umgebungen anderer Systemsprachen (C/C++)

Compile Targets: x86_46, arm, arch64, wasm, i686, i586, etc.

Sprachkonzepte

Schlüsselwort-Wolke

Basis-Konzepte

  • Unveränderlichkeit ist Standard.
  • Genau einen mutable Eigentümer (Ownership).
  • Lifetimes/Scopes {'a {'a'b} 'a}
  • Ressourcenbelegung ist Initialisierung (RAII).

..sind hauptsächlich in Klasse "Speicher Management" | RustLang Buch über Common-Concepts

Basis-Konzepte

  • Unveränderlichkeit ist Standard.
  • Genau einen mutable Eigentümer (Ownership).
  • Lifetimes/Scopes {'a {'a'b} 'a}
  • Ressourcenbelegung ist Initialisierung (RAII).
  • No-Null-Referenz: &-[immer]->Etwas
  • Pattern Matching
  • Errors 🪲 sind Werte, nichts außergewöhnliches..
  • Compiler & Clippy 📎
    Anti-Anti-Pattern-Enforcer

..sind hauptsächlich in Klasse "Speicher Management" | RustLang Buch über Common-Concepts

Ownership

Ownership

					
					fn main() {
						let name = String::from("Ferris the Crab 🦀")
						let player = name;

						println!("Ich bin {name}");
					}
					
				

Ownership


					fn main() {
						let name = String::from("Ferris the Crab 🦀")
						let player = name;  // move name -> player

						println!("Ich bin {name}");  // ❌ borrow of moved value
					}
					

Ownership


					fn main() {
						let name = String::from("Ferris the Crab 🦀")
						let player = name.clone();  // move name -> player

						println!("Ich bin {name}");  // ✅
					}
					

Borrowing

Ich leih Dir das kurz zum Spielen,
wills aber wieder zurück haben!

Borrowing


						fn main() {
							//...
						
							let mut scores = vec![4, 9, 6, 2, 0];
							let first: &i32 = scores.first().unwrap_or(&0);
							scores.push(3); // benötigt `mut`
						
							println!("Erstes Ergebnis: {first}");
						}
						

Borrowing


						fn main() {
							//...
						
							let mut scores = vec![4, 9, 6, 2, 0];
							// borrow of first value..
							let first: &i32 = scores.first().unwrap_or(&0);
							scores.push(3); // ❌ possible reallocation of scores
						
							println!("Erstes Ergebnis: {first}");
						}
						

Borrowing


						fn main() {
							//...
						
							let mut scores = vec![4, 9, 6, 2, 0];
							scores.push(3);
							let first: &i32 = scores.first().unwrap_or(&0);
						
							println!("Erstes Ergebnis: {first}"); // ..4
						}
						

Lifetimes

Alles hat ein Ende.. ☠️

Lifetimes


						fn main() {
							//...
						
							let mut scores = vec![4, 9, 6, 2, 0];
							scores.push(3);
							let first: &i32 = scores.first().unwrap_or(&0);
						
							println!("Erstes Ergebnis: {first}"); // ..4
						}
						

Lifetimes


						fn main() {
							//...
						
							let mut scores = vec![4, 9, 6, 2, 0];
							{
								let first: &i32 = scores.first().unwrap_or(&0);
								// mach irgendwas mit erstem Element..
							}
							scores.push(3);

							println!("Erstes Ergebnis: {first}"); 
						}
						

Lifetimes


						fn main() {
							//...
						
							let mut scores = vec![4, 9, 6, 2, 0];
							{
								let first: &i32 = scores.first().unwrap_or(&0);
								// mach irgendwas mit erstem Element..
							}
							scores.push(3);

							// ❌ `first` existiert nicht.
							println!("Erstes Ergebnis: {first}");  
						}
						

Lifetimes


						fn main() {
							//...
						
							let mut scores = vec![4, 9, 6, 2, 0];
							{
								let first: &i32 = scores.first().unwrap_or(&0);
								// mach irgendwas mit erstem Element..
								println!("Erstes Ergebnis: {first}");  // ✅
								drop(first); // passiert implizit durch RAII
							}
							scores.push(3);
							//...
							println!("Ergebnisse: {:?}", scores);
							// stdout: Ergebnisse: [4, 9, 6, 2, 0, 3]
						}
						

Lifetimes <'Label> ⤴️

Nicht alles kann zur Compile-Zeit geprüft werden .. oder?

Lifetimes <'Label> ⤴️


						fn main() {
							get_name(
								true,
								"Ferris the Crab 🦀",
								"Ferry"
							);
						}
						
						fn get_name(
							is_anonym: bool,
							player: &str,
							nickname: &str
						) -> &str {
							if is_anonym { nickname } else { player }
						}
						

Lifetimes <'Label> ⤴️


						fn main() {
							get_name(
								true,
								"Ferris the Crab 🦀",
								"Ferry"
							);
						}
						// ❌ explicit lifetime required
						fn get_name(
							is_anonym: bool,
							player: &str,
							nickname: &str
						) -> &str {
							if is_anonym { nickname } else { player }
						}
						

Lifetimes <'Label> ⤴️


						fn main() {
							get_name(
								true,
								"Ferris the Crab 🦀",
								"Ferry"
							);
						}
						// ✅
						fn get_name<'lbl>(
							is_anonym: bool,
							player: &'lbl str,
							nickname: &'lbl str
						) -> &'lbl str {
							if is_anonym { nickname } else { player }
						}
						

Lifetimes <'Label> ⤴️


						fn main() {
							get_name(
								true,
								"Ferris the Crab 🦀",
								"Ferry"
							);
						}
						// ✅
						fn get_name<'lbl>(
							is_anonym: bool,
							player: &'lbl str,
							nickname: &'lbl str
						) -> &'lbl str {
							if is_anonym { nickname } else { player }
						}
						

Datenstrukturen

Etwas Struktur bitte!

Datenstrukturen - Struct/Enum


						struct Player<'same> {
							name: &'same str,
							nickname: &'same str,
							score: Vec<i32>,
							age: u8,
							difficulty: &'same Difficulty,
						}
						
						enum Difficulty { Easy , Normal, Hard(&'static str) }
						enum Visibility { Public, Anonym }
						

Datenstrukturen - Match


						impl<'same> Player<'same> {
							fn get_player(
								&self,
								anonymity: Visibility,
							) -> (&'same str, i32) {
								let overall_score = self.score.iter().sum();
								match anonymity {
									Visibility::Public => (&self.nickname, overall_score),
									Visibility::Anonym => (&self.name, overall_score)
								}
							}
						}
						

Datenstrukturen - Destructuring


						fn main() {
							let player = Player {
								name: "Ferris the Crab 🦀",
								nickname: "Ferry",
								score: vec![4, 8, 4],
								age: 12,
								difficulty: &Difficulty::Hard("😈"),
							};
						
							let (public_name, overall_score) =
								player.get_player(Visibility::Public);
							println!("{public_name} hat insgesamt {overall_score} Punkte!");
							// Ferry hat insgesamt 16 Punkte! ✅
						}				
						

Tradeoffs

Wann und Wie?

Tradeoffs

Frage.. Rust 🦀 | Java ♨️
Speichersicher ohne GC. Speichersicher mit GC.
Zero-Cost Abstractions Zur Laufzeit optimierender JIT
Fängt Großteil der Fehler zur Compile-Zeit ab. Fehler können behandelt werden, Laufzeitfehler werden nicht strikt verhindert.

Tradeoffs

Frage.. Rust 🦀 | Java ♨️
Speichersicher ohne GC. Speichersicher mit GC.
Zero-Cost Abstractions Zur Laufzeit optimierender JIT
Fängt Großteil der Fehler zur Compile-Zeit ab. Fehler können behandelt werden, Laufzeitfehler werden nicht strikt verhindert.
Use-Cases General: Web, IoT, Robotik, BigData, (G|T)UI Business: Web, Finanzen, BigData, (G|T)UI
Pakete &
Versionen 📦
Alles über integrierte CLI:
`cargo`, `rustup`, `rustc`
Viele SDKs & Laufzeiten (JVMs),
optionale Paket-Manager

🦀 WASM 🕸️ Demo

Fin.