Rust -> rust && .notCompiling
This commit is contained in:
parent
025f075209
commit
6e9b01aa28
@ -1,5 +1,5 @@
|
|||||||
:experimental:
|
:experimental:
|
||||||
:docdatetime: 2022-06-14T12:26:06.567Z
|
:docdatetime: 2022-08-10T17:04:53+02:00
|
||||||
|
|
||||||
= Hello world
|
= Hello world
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ spezielle Art Funktion?), die einfach auf stdout printed.
|
|||||||
|
|
||||||
|
|
||||||
~*In[2]:*~
|
~*In[2]:*~
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
println!("Hello world!");
|
println!("Hello world!");
|
||||||
----
|
----
|
||||||
@ -31,7 +31,7 @@ Ein komplettes Programm zum Kompilieren hätte also den folgenden Inhalt:
|
|||||||
|
|
||||||
|
|
||||||
~*In[3]:*~
|
~*In[3]:*~
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Hello world!");
|
println!("Hello world!");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
:experimental:
|
:experimental:
|
||||||
:docdatetime: 2022-06-14T12:26:06.567Z
|
:docdatetime: 2022-08-10T17:04:53+02:00
|
||||||
|
|
||||||
= Cargo
|
= Cargo
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
:experimental:
|
:experimental:
|
||||||
:docdatetime: 2022-06-14T12:27:14.473Z
|
:docdatetime: 2022-08-10T17:04:53+02:00
|
||||||
|
|
||||||
= Erstes Spiel
|
= Erstes Spiel
|
||||||
|
|
||||||
@ -13,7 +13,7 @@ Das Projekt wird wie in Notebook 01 beschrieben erstellt.
|
|||||||
|
|
||||||
|
|
||||||
~*In[2]:*~
|
~*In[2]:*~
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
:dep evcxr_input
|
:dep evcxr_input
|
||||||
// Das ^ ist für Jupyter
|
// Das ^ ist für Jupyter
|
||||||
@ -83,7 +83,7 @@ Die crate `rand` kann jetzt im Code verwendet werden.
|
|||||||
|
|
||||||
|
|
||||||
~*In[3]:*~
|
~*In[3]:*~
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
:dep rand = "0.3.15"
|
:dep rand = "0.3.15"
|
||||||
// Das ^ ist von Jupyter
|
// Das ^ ist von Jupyter
|
||||||
@ -109,7 +109,7 @@ Ein Fehler?
|
|||||||
|
|
||||||
|
|
||||||
~*In[4]:*~
|
~*In[4]:*~
|
||||||
[source, Rust]
|
[source.notCompiling, rust]
|
||||||
----
|
----
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
@ -138,7 +138,7 @@ Wir müssen unser guess also umwandeln:
|
|||||||
|
|
||||||
|
|
||||||
~*In[5]:*~
|
~*In[5]:*~
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
let guess: u32 = guess.trim().parse().expect("Please type a number!");
|
let guess: u32 = guess.trim().parse().expect("Please type a number!");
|
||||||
----
|
----
|
||||||
@ -154,7 +154,7 @@ Jetzt sollte das Vergleichen auch klappen!
|
|||||||
|
|
||||||
|
|
||||||
~*In[6]:*~
|
~*In[6]:*~
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
@ -178,7 +178,7 @@ Damit wir mehrmals raten können, brauchen wir eine Schleife.
|
|||||||
|
|
||||||
|
|
||||||
~*In[7]:*~
|
~*In[7]:*~
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
let secret_number: u32 = rand::thread_rng().gen_range(1, 101);
|
let secret_number: u32 = rand::thread_rng().gen_range(1, 101);
|
||||||
loop {
|
loop {
|
||||||
@ -226,7 +226,7 @@ Offensichtlich müssen wir die Schleife dann abbrechen.
|
|||||||
|
|
||||||
|
|
||||||
~*In[8]:*~
|
~*In[8]:*~
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
let secret_number: u32 = rand::thread_rng().gen_range(1, 101);
|
let secret_number: u32 = rand::thread_rng().gen_range(1, 101);
|
||||||
loop {
|
loop {
|
||||||
@ -277,7 +277,7 @@ Zahl eingibt. Das können wir auch relativ einfach fixen:
|
|||||||
|
|
||||||
|
|
||||||
~*In[9]:*~
|
~*In[9]:*~
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
loop {
|
loop {
|
||||||
let mut guess = evcxr_input::get_string("Number? ");
|
let mut guess = evcxr_input::get_string("Number? ");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
:experimental:
|
:experimental:
|
||||||
:docdatetime: 2022-07-05T17:57:48+02:00
|
:docdatetime: 2022-08-10T17:04:53+02:00
|
||||||
|
|
||||||
= Konzepte
|
= Konzepte
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ In anderen Sprachen ist das häufig `const` - in Rust gibt es aber auch `const`!
|
|||||||
|
|
||||||
Das Folgende funktioniert also nicht:
|
Das Folgende funktioniert also nicht:
|
||||||
|
|
||||||
[source, Rust]
|
[source.notCompiling, Rust]
|
||||||
----
|
----
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = "Hello world!";
|
let x = "Hello world!";
|
||||||
@ -25,7 +25,7 @@ fn main() {
|
|||||||
|
|
||||||
Damit Variablen mutable sind, muss `mut` genutzt werden:
|
Damit Variablen mutable sind, muss `mut` genutzt werden:
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut x = "Hello world!";
|
let mut x = "Hello world!";
|
||||||
@ -46,7 +46,7 @@ Die Konvention für Konstanten ist snake case all caps.
|
|||||||
|
|
||||||
Ein Beispiel dafür ist folgendes:
|
Ein Beispiel dafür ist folgendes:
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
const MINUTES_IN_A_DAY: u32 = 24 * 60;
|
const MINUTES_IN_A_DAY: u32 = 24 * 60;
|
||||||
----
|
----
|
||||||
@ -59,7 +59,7 @@ Anfangs habe ich es falsch verstanden: Ich dachte Shadowing wäre, dass eine Var
|
|||||||
Allerdings ist es mehr ein "Reuse" eines alten Namens.
|
Allerdings ist es mehr ein "Reuse" eines alten Namens.
|
||||||
Ein Beispiel:
|
Ein Beispiel:
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = 5;
|
let x = 5;
|
||||||
@ -86,7 +86,7 @@ Wenn das nicht geht, muss manuell ein Typ festgelegt werden.
|
|||||||
|
|
||||||
Ein Beispiel:
|
Ein Beispiel:
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
let guess: u32 = "42".parse().expect("Not a number!");
|
let guess: u32 = "42".parse().expect("Not a number!");
|
||||||
----
|
----
|
||||||
@ -119,7 +119,7 @@ Interessant ist, dass es zusätzliche Methoden für alles gibt (nicht nur `add`)
|
|||||||
- `overflowing_add` gibt einen Boolean, ob ein Overflow auftritt
|
- `overflowing_add` gibt einen Boolean, ob ein Overflow auftritt
|
||||||
- `saturating_add` bleibt beim Maximum oder Minimum des verfügbaren Bereiches
|
- `saturating_add` bleibt beim Maximum oder Minimum des verfügbaren Bereiches
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
let number: u8 = 254;
|
let number: u8 = 254;
|
||||||
println!("{}", number.wrapping_add(2));
|
println!("{}", number.wrapping_add(2));
|
||||||
@ -151,7 +151,7 @@ Sie sind aber schreibbar, wenn `mut` zur Initialisierung genutzt wird, also nich
|
|||||||
|
|
||||||
Ein paar Beispiele als Code:
|
Ein paar Beispiele als Code:
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
let x: (f32, char, u8) = (1.0, '🐧', 3);
|
let x: (f32, char, u8) = (1.0, '🐧', 3);
|
||||||
//_x.0 = 2.0; // geht nicht, da x nicht mut ist.
|
//_x.0 = 2.0; // geht nicht, da x nicht mut ist.
|
||||||
@ -178,7 +178,7 @@ Für "Arrays" mit veränderbarer Länge gibt es Vektoren.
|
|||||||
|
|
||||||
Wieder etwas Code:
|
Wieder etwas Code:
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
let x: [i32; 5] = [1, 2, 3, 4, 5];
|
let x: [i32; 5] = [1, 2, 3, 4, 5];
|
||||||
// ^ so sieht der Datentyp aus
|
// ^ so sieht der Datentyp aus
|
||||||
@ -198,7 +198,7 @@ Sind wie normale Funktionen in C auch. Keyword ist `fn`.
|
|||||||
|
|
||||||
Beispiel:
|
Beispiel:
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
fn calculate_sum(a: i32, b: i32) -> i64 {
|
fn calculate_sum(a: i32, b: i32) -> i64 {
|
||||||
// Statements können natürlich normal genutzt werden
|
// Statements können natürlich normal genutzt werden
|
||||||
@ -233,7 +233,7 @@ Es gibt auch noch spezielle Docstrings, aber das kommt später.
|
|||||||
|
|
||||||
Beispiel für labels:
|
Beispiel für labels:
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
fn main() {
|
fn main() {
|
||||||
'outer: loop {
|
'outer: loop {
|
||||||
@ -253,7 +253,7 @@ fn main() {
|
|||||||
`break` mit Wert ist Rückgabe.
|
`break` mit Wert ist Rückgabe.
|
||||||
Einfaches Beispiel:
|
Einfaches Beispiel:
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut counter = 0;
|
let mut counter = 0;
|
||||||
@ -279,7 +279,7 @@ fn main() {
|
|||||||
|
|
||||||
Looped durch eine Collection (wie in Python).
|
Looped durch eine Collection (wie in Python).
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
fn main() {
|
fn main() {
|
||||||
let a = [10, 20, 30, 40, 50];
|
let a = [10, 20, 30, 40, 50];
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
:experimental:
|
:experimental:
|
||||||
:docdatetime: 2022-07-05T15:32:40+02:00
|
:docdatetime: 2022-08-10T17:04:53+02:00
|
||||||
|
|
||||||
= Ownership
|
= Ownership
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ Dieser String-Typ hat den Vorteil, dass er eine dynamische Länge hat und damit
|
|||||||
|
|
||||||
Ein Beispiel:
|
Ein Beispiel:
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
let mut x = String::from("Hello"); // Legt "dynamischen" String an
|
let mut x = String::from("Hello"); // Legt "dynamischen" String an
|
||||||
x.push_str(" world!"); // Konkatiniert an den String
|
x.push_str(" world!"); // Konkatiniert an den String
|
||||||
@ -48,7 +48,7 @@ Theoretisch kann `x` natürlich dann überschrieben werden, mit einem String and
|
|||||||
|
|
||||||
=== Move
|
=== Move
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
let x = 5; // Int -> feste Größe und auf Stack
|
let x = 5; // Int -> feste Größe und auf Stack
|
||||||
let y = x;
|
let y = x;
|
||||||
@ -110,7 +110,7 @@ Damit werden (unter anderem) Race Conditions schon beim Compilen verhindert.
|
|||||||
|
|
||||||
=== Dangling references
|
=== Dangling references
|
||||||
|
|
||||||
[source, Rust]
|
[source.notCompiling, rust]
|
||||||
----
|
----
|
||||||
fn dangle() -> &String {
|
fn dangle() -> &String {
|
||||||
let s = String::from("hello");
|
let s = String::from("hello");
|
||||||
@ -133,7 +133,7 @@ Nur so kann multithreading etc. funktionieren.
|
|||||||
Dafür hat Rust den Slice-Datentyp.
|
Dafür hat Rust den Slice-Datentyp.
|
||||||
Der funktioniert ähnlich wie Array-Ranges in Python.
|
Der funktioniert ähnlich wie Array-Ranges in Python.
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
let s = String::from("hello world");
|
let s = String::from("hello world");
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
:experimental:
|
:experimental:
|
||||||
:docdatetime: 2022-07-05T17:45:24+02:00
|
:docdatetime: 2022-08-10T17:04:53+02:00
|
||||||
|
|
||||||
= Structs
|
= Structs
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ Man kann damit neue Datentypen machen.
|
|||||||
|
|
||||||
=== "Normale" Structs
|
=== "Normale" Structs
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
struct User {
|
struct User {
|
||||||
active: bool,
|
active: bool,
|
||||||
@ -47,7 +47,7 @@ Wenn die Variable heißt wie das Feld, kann man auch statt `email: email` einfac
|
|||||||
|
|
||||||
Wenn man ein neues Struct aus einem alten mit Updates erstellen will, geht das auch mit einer Art Spread-Parameter:
|
Wenn man ein neues Struct aus einem alten mit Updates erstellen will, geht das auch mit einer Art Spread-Parameter:
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
let user2 = User {
|
let user2 = User {
|
||||||
email: String::from("another@example.com"),
|
email: String::from("another@example.com"),
|
||||||
@ -62,7 +62,7 @@ Hätten wir jetzt auch noch einen neuen `username` gesetzt (auch ein String) und
|
|||||||
|
|
||||||
=== Tupel Structs
|
=== Tupel Structs
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
struct RGBColor(u8, u8, u8);
|
struct RGBColor(u8, u8, u8);
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ Sind nutzbar wie Tupel (destrucuture und `.index` zum Zugriff auf Werte), allerd
|
|||||||
|
|
||||||
=== Unit-Like Structs
|
=== Unit-Like Structs
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
struct AlwaysEqual;
|
struct AlwaysEqual;
|
||||||
----
|
----
|
||||||
@ -119,7 +119,7 @@ Tatsächlich ist der sehr einfach und sehr OOPig.
|
|||||||
|
|
||||||
Die folgenden Beispiele sollten relativ viel erklären:
|
Die folgenden Beispiele sollten relativ viel erklären:
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
struct Rectangle {
|
struct Rectangle {
|
||||||
width: u32,
|
width: u32,
|
||||||
@ -184,7 +184,7 @@ fn main() {
|
|||||||
Eine Methode kann auch `&mut self` als ersten Parameter haben.
|
Eine Methode kann auch `&mut self` als ersten Parameter haben.
|
||||||
Dann können auch Felder geschrieben werden. In diesem Fall werden Referenzen aber invalidiert!
|
Dann können auch Felder geschrieben werden. In diesem Fall werden Referenzen aber invalidiert!
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
struct Rectangle {
|
struct Rectangle {
|
||||||
width: u32,
|
width: u32,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
:experimental:
|
:experimental:
|
||||||
:docdatetime: 2022-07-25T20:00:23+02:00
|
:docdatetime: 2022-08-10T17:04:53+02:00
|
||||||
|
|
||||||
= Enums und Pattern Matching
|
= Enums und Pattern Matching
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ Grundsätzlich ist ein "Enum" in Rust näher am "Union" würde ich denken.
|
|||||||
Ein einfaches Beispiel für ist der Typ `Option<T>` (vergleichbar mit Python oder Java `Optional`).
|
Ein einfaches Beispiel für ist der Typ `Option<T>` (vergleichbar mit Python oder Java `Optional`).
|
||||||
Dieser ist entweder `None` oder `Some(value: T)` - es kann also ein Wert zusätzlich zur "Definition" beinhalten.
|
Dieser ist entweder `None` oder `Some(value: T)` - es kann also ein Wert zusätzlich zur "Definition" beinhalten.
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
enum Farbcode {
|
enum Farbcode {
|
||||||
Hex,
|
Hex,
|
||||||
@ -30,7 +30,7 @@ Die Funktion kann dann je nach Typ verschieden funktionieren.
|
|||||||
|
|
||||||
Wie schon erwähnt, kann so ein Enum-Wert auch Werte beinhalten, um das zu machen, schreiben wir den Code einfach um:
|
Wie schon erwähnt, kann so ein Enum-Wert auch Werte beinhalten, um das zu machen, schreiben wir den Code einfach um:
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
enum Farbcode {
|
enum Farbcode {
|
||||||
Hex(String),
|
Hex(String),
|
||||||
@ -54,7 +54,7 @@ Natürlich können die Structs jeder Art sein.
|
|||||||
Enums sind aber auch selber eine Art Struct.
|
Enums sind aber auch selber eine Art Struct.
|
||||||
Also können wir für Enums auch Methoden definieren wie für Structs.
|
Also können wir für Enums auch Methoden definieren wie für Structs.
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
impl Farbcode {
|
impl Farbcode {
|
||||||
fn to_css_string(&self) {
|
fn to_css_string(&self) {
|
||||||
@ -84,7 +84,7 @@ So wie Rust bis jetzt klang, kann wahrscheinlich jedem Datentypen ein "match-Tra
|
|||||||
Aber ganz einfach: Angenommen wir wollen die Methode `to_css_string` von oben implementieren.
|
Aber ganz einfach: Angenommen wir wollen die Methode `to_css_string` von oben implementieren.
|
||||||
Diese Methode muss ja, je nach Typ, völlig unterschiedlich funktionieren.
|
Diese Methode muss ja, je nach Typ, völlig unterschiedlich funktionieren.
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
enum Farbcode {
|
enum Farbcode {
|
||||||
Hex(String),
|
Hex(String),
|
||||||
@ -126,7 +126,7 @@ Der Unterschied ist, dass bei `other` noch der Inhalt genutzt werden kann, bei `
|
|||||||
Dieses if-Konstrukt nutzt man am besten, wenn man nur auf eine einzelne Variante eines Enums prüfen möchte.
|
Dieses if-Konstrukt nutzt man am besten, wenn man nur auf eine einzelne Variante eines Enums prüfen möchte.
|
||||||
Letzendlich ist es ganz simpel:
|
Letzendlich ist es ganz simpel:
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum Muenzwurf {
|
enum Muenzwurf {
|
||||||
|
@ -50,7 +50,7 @@ Im Hauptprogramm kann mit `mod modulname;` das Modul eingebunden werden. Gesucht
|
|||||||
Zusätzlich kann auch direkt inline ein Modul erstellt werden.
|
Zusätzlich kann auch direkt inline ein Modul erstellt werden.
|
||||||
Ein Beispiel:
|
Ein Beispiel:
|
||||||
|
|
||||||
[source.notCompiling, Rust]
|
[source.notCompiling, rust]
|
||||||
----
|
----
|
||||||
mod testmodul {
|
mod testmodul {
|
||||||
mod nested_modul {
|
mod nested_modul {
|
||||||
@ -77,7 +77,7 @@ Das funktioniert noch *nicht*.
|
|||||||
Denn standardmäßig ist alles private, was nicht explizit public ist.
|
Denn standardmäßig ist alles private, was nicht explizit public ist.
|
||||||
Damit wir den obigen Aufruf machen können, muss der Code so aussehen:
|
Damit wir den obigen Aufruf machen können, muss der Code so aussehen:
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
mod testmodul {
|
mod testmodul {
|
||||||
pub mod nested_modul {
|
pub mod nested_modul {
|
||||||
@ -114,7 +114,7 @@ In Modulen können natürlich auch Structs und Enums verwendet werden.
|
|||||||
Bei Structs ist die Besonderheit, dass die einzelnen Attribute auch wieder private oder public sein können.
|
Bei Structs ist die Besonderheit, dass die einzelnen Attribute auch wieder private oder public sein können.
|
||||||
So kann man folgendes machen:
|
So kann man folgendes machen:
|
||||||
|
|
||||||
[source, Rust]
|
[source, rust]
|
||||||
----
|
----
|
||||||
mod testmodul {
|
mod testmodul {
|
||||||
pub struct Teststruct {
|
pub struct Teststruct {
|
||||||
|
Loading…
Reference in New Issue
Block a user