Rust -> rust && .notCompiling

This commit is contained in:
Daniel Kluge 2022-08-10 17:04:53 +02:00
parent 025f075209
commit 6e9b01aa28
8 changed files with 52 additions and 52 deletions

View File

@ -1,5 +1,5 @@
:experimental:
:docdatetime: 2022-06-14T12:26:06.567Z
:docdatetime: 2022-08-10T17:04:53+02:00
= Hello world
@ -12,7 +12,7 @@ spezielle Art Funktion?), die einfach auf stdout printed.
~*In[2]:*~
[source, Rust]
[source, rust]
----
println!("Hello world!");
----
@ -31,7 +31,7 @@ Ein komplettes Programm zum Kompilieren hätte also den folgenden Inhalt:
~*In[3]:*~
[source, Rust]
[source, rust]
----
fn main() {
println!("Hello world!");
@ -40,7 +40,7 @@ fn main() {
Kompiliert und ausgeführt wird es dann über folgende Befehle:
[source,bash]
[source, bash]
----
$ rustc main.rs
$ ./main

View File

@ -1,5 +1,5 @@
:experimental:
:docdatetime: 2022-06-14T12:26:06.567Z
:docdatetime: 2022-08-10T17:04:53+02:00
= Cargo
@ -11,7 +11,7 @@ Cargo ist Rusts package manager. +
Um ein neues Cargo-Projekt zu erstellen, braucht es das folgende
Command:
[source,bash]
[source, bash]
----
$ cargo new projektname --bin
----
@ -27,7 +27,7 @@ und `Cargo.toml` erstellt.
Unangetastet sieht die Datei so aus:
[source,toml]
[source, toml]
----
[package]
name = "projektname"
@ -48,7 +48,7 @@ Die Main-Datei ist mit ``Hello World'' gefüllt.
=== cargo build
[source,bash]
[source, bash]
----
$ cargo build
$ ./target/debug/projektname

View File

@ -1,5 +1,5 @@
:experimental:
:docdatetime: 2022-06-14T12:27:14.473Z
:docdatetime: 2022-08-10T17:04:53+02:00
= Erstes Spiel
@ -13,7 +13,7 @@ Das Projekt wird wie in Notebook 01 beschrieben erstellt.
~*In[2]:*~
[source, Rust]
[source, rust]
----
:dep evcxr_input
// Das ^ ist für Jupyter
@ -69,7 +69,7 @@ auftreten
Für eine random Zahl brauchen wir die erste Dependency. +
Also `Cargo.toml` bearbeiten:
[source,toml]
[source, toml]
----
[dependencies]
rand = "0.3.14"
@ -83,7 +83,7 @@ Die crate `rand` kann jetzt im Code verwendet werden.
~*In[3]:*~
[source, Rust]
[source, rust]
----
:dep rand = "0.3.15"
// Das ^ ist von Jupyter
@ -109,7 +109,7 @@ Ein Fehler?
~*In[4]:*~
[source, Rust]
[source.notCompiling, rust]
----
use std::cmp::Ordering;
@ -138,7 +138,7 @@ Wir müssen unser guess also umwandeln:
~*In[5]:*~
[source, Rust]
[source, rust]
----
let guess: u32 = guess.trim().parse().expect("Please type a number!");
----
@ -154,7 +154,7 @@ Jetzt sollte das Vergleichen auch klappen!
~*In[6]:*~
[source, Rust]
[source, rust]
----
use std::cmp::Ordering;
@ -178,7 +178,7 @@ Damit wir mehrmals raten können, brauchen wir eine Schleife.
~*In[7]:*~
[source, Rust]
[source, rust]
----
let secret_number: u32 = rand::thread_rng().gen_range(1, 101);
loop {
@ -226,7 +226,7 @@ Offensichtlich müssen wir die Schleife dann abbrechen.
~*In[8]:*~
[source, Rust]
[source, rust]
----
let secret_number: u32 = rand::thread_rng().gen_range(1, 101);
loop {
@ -277,7 +277,7 @@ Zahl eingibt. Das können wir auch relativ einfach fixen:
~*In[9]:*~
[source, Rust]
[source, rust]
----
loop {
let mut guess = evcxr_input::get_string("Number? ");

View File

@ -1,5 +1,5 @@
:experimental:
:docdatetime: 2022-07-05T17:57:48+02:00
:docdatetime: 2022-08-10T17:04:53+02:00
= 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:
[source, Rust]
[source.notCompiling, Rust]
----
fn main() {
let x = "Hello world!";
@ -25,7 +25,7 @@ fn main() {
Damit Variablen mutable sind, muss `mut` genutzt werden:
[source, Rust]
[source, rust]
----
fn main() {
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:
[source, Rust]
[source, rust]
----
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.
Ein Beispiel:
[source, Rust]
[source, rust]
----
fn main() {
let x = 5;
@ -86,7 +86,7 @@ Wenn das nicht geht, muss manuell ein Typ festgelegt werden.
Ein Beispiel:
[source, Rust]
[source, rust]
----
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
- `saturating_add` bleibt beim Maximum oder Minimum des verfügbaren Bereiches
[source, Rust]
[source, rust]
----
let number: u8 = 254;
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:
[source, Rust]
[source, rust]
----
let x: (f32, char, u8) = (1.0, '🐧', 3);
//_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:
[source, Rust]
[source, rust]
----
let x: [i32; 5] = [1, 2, 3, 4, 5];
// ^ so sieht der Datentyp aus
@ -198,7 +198,7 @@ Sind wie normale Funktionen in C auch. Keyword ist `fn`.
Beispiel:
[source, Rust]
[source, rust]
----
fn calculate_sum(a: i32, b: i32) -> i64 {
// 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:
[source, Rust]
[source, rust]
----
fn main() {
'outer: loop {
@ -253,7 +253,7 @@ fn main() {
`break` mit Wert ist Rückgabe.
Einfaches Beispiel:
[source, Rust]
[source, rust]
----
fn main() {
let mut counter = 0;
@ -279,7 +279,7 @@ fn main() {
Looped durch eine Collection (wie in Python).
[source, Rust]
[source, rust]
----
fn main() {
let a = [10, 20, 30, 40, 50];

View File

@ -1,5 +1,5 @@
:experimental:
:docdatetime: 2022-07-05T15:32:40+02:00
:docdatetime: 2022-08-10T17:04:53+02:00
= Ownership
@ -35,7 +35,7 @@ Dieser String-Typ hat den Vorteil, dass er eine dynamische Länge hat und damit
Ein Beispiel:
[source, Rust]
[source, rust]
----
let mut x = String::from("Hello"); // Legt "dynamischen" String an
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
[source, Rust]
[source, rust]
----
let x = 5; // Int -> feste Größe und auf Stack
let y = x;
@ -110,7 +110,7 @@ Damit werden (unter anderem) Race Conditions schon beim Compilen verhindert.
=== Dangling references
[source, Rust]
[source.notCompiling, rust]
----
fn dangle() -> &String {
let s = String::from("hello");
@ -133,7 +133,7 @@ Nur so kann multithreading etc. funktionieren.
Dafür hat Rust den Slice-Datentyp.
Der funktioniert ähnlich wie Array-Ranges in Python.
[source, Rust]
[source, rust]
----
let s = String::from("hello world");

View File

@ -1,5 +1,5 @@
:experimental:
:docdatetime: 2022-07-05T17:45:24+02:00
:docdatetime: 2022-08-10T17:04:53+02:00
= Structs
@ -17,7 +17,7 @@ Man kann damit neue Datentypen machen.
=== "Normale" Structs
[source, Rust]
[source, rust]
----
struct User {
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:
[source, Rust]
[source, rust]
----
let user2 = User {
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
[source, Rust]
[source, rust]
----
struct RGBColor(u8, u8, u8);
@ -75,7 +75,7 @@ Sind nutzbar wie Tupel (destrucuture und `.index` zum Zugriff auf Werte), allerd
=== Unit-Like Structs
[source, Rust]
[source, rust]
----
struct AlwaysEqual;
----
@ -119,7 +119,7 @@ Tatsächlich ist der sehr einfach und sehr OOPig.
Die folgenden Beispiele sollten relativ viel erklären:
[source, Rust]
[source, rust]
----
struct Rectangle {
width: u32,
@ -184,7 +184,7 @@ fn main() {
Eine Methode kann auch `&mut self` als ersten Parameter haben.
Dann können auch Felder geschrieben werden. In diesem Fall werden Referenzen aber invalidiert!
[source, Rust]
[source, rust]
----
struct Rectangle {
width: u32,

View File

@ -1,5 +1,5 @@
:experimental:
:docdatetime: 2022-07-25T20:00:23+02:00
:docdatetime: 2022-08-10T17:04:53+02:00
= 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`).
Dieser ist entweder `None` oder `Some(value: T)` - es kann also ein Wert zusätzlich zur "Definition" beinhalten.
[source, Rust]
[source, rust]
----
enum Farbcode {
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:
[source, Rust]
[source, rust]
----
enum Farbcode {
Hex(String),
@ -54,7 +54,7 @@ Natürlich können die Structs jeder Art sein.
Enums sind aber auch selber eine Art Struct.
Also können wir für Enums auch Methoden definieren wie für Structs.
[source, Rust]
[source, rust]
----
impl Farbcode {
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.
Diese Methode muss ja, je nach Typ, völlig unterschiedlich funktionieren.
[source, Rust]
[source, rust]
----
enum Farbcode {
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.
Letzendlich ist es ganz simpel:
[source, Rust]
[source, rust]
----
#[derive(Debug)]
enum Muenzwurf {

View File

@ -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.
Ein Beispiel:
[source.notCompiling, Rust]
[source.notCompiling, rust]
----
mod testmodul {
mod nested_modul {
@ -77,7 +77,7 @@ Das funktioniert noch *nicht*.
Denn standardmäßig ist alles private, was nicht explizit public ist.
Damit wir den obigen Aufruf machen können, muss der Code so aussehen:
[source, Rust]
[source, rust]
----
mod testmodul {
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.
So kann man folgendes machen:
[source, Rust]
[source, rust]
----
mod testmodul {
pub struct Teststruct {