Rust - ghdrako/doc_snipets GitHub Wiki

Documentation

Online books

Video tutorials

Blogs

learning excercise

Library

Rust

  • DARPA converter C na Rust
  • Rust in Linux Kernel - wojna o formatowanie include w jednej linijce
  • Garbage Collector - micro freezy np java minecraft zaleznie od ramu moze byc agresywniejszy
  • C problemy seg fault wiszace wskazniki dungling pointer
  • Memory safety
  • Zero-Cost Abstraction - dostep od abstrakcji wysokiego poziomu do poziomu hardware wiec tez do systemow embeded. Mozna odrzucic biblioteke standardowa i pisac w stm32
  • Thread safety - ownership model - data race, zaglodzenia watkow
  • Performance
  • od 2015
rustc --version
cargo --version

Stacjait

Cargo.toml Edytion =2025 - wersja jezyka

Cargo.lock - nie modyfikujemy

cargo run  - kompiluje i uruchamia od razu -- odpalanie binarki
cargo run hello_world -- podajemy nawe binarki zdefiniowanej w Cargo.toml
cargo run hello_world
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.05s   <-- profil
     Running `target\debug\hello_world.exe hello_world`
Hello, world!
Result of addition is: 69
fn

libs

Cargo.toml w katalogu biblioteki:

[package]
name = "my_libs"
version = "0.1.0"
edition = "2024"

[lib]
path = "my_libs.rs"

Uzycie w Cargo.toml aplikacji:

[dependencies]
my_libs = { path = "./libs" }
tokio = { version = "1.0", features = ["full"] }
version = "*"  - dowolana wersja biblioteki
#includemain(no_std) - nie includj biblioteki standardowej dla embeded  

println

mylibs to modul biblioteka

my_libs.rs

pub mod add;
pub mod sub;

add.rs

pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

// Test with built-in test framework
// Run with: cargo test -p my_libs
//           cargo test --doc -p my_libs
#[cfg(test)]
mod tests {
    use super::*;  // super czyli z modulu nadrzednego bo moduly mozna zagniezdzac. Nie nalezy nadmiernie zagniezdzac moduly

    #[test]
    fn test_add() {
        assert_eq!(add(34, 35), 69);
    }

    #[test]
    fn test_add_neg() {
        assert_ne!(add(34, 35), 2137);
    }

    #[test]
    fn test_wrong() {
        assert_eq!(add(34, 35), -123);
    }
}

RUST_BACTRACE=1; cargo test -p my_libs -pokazuje szczewgolowe inforacje - sprawdzic skladnie

doc testy

// Defining doc-test

/// Substraction - substract two numbers!
///
/// This function takes two arguments and substracts them from each other.
/// Code blocks start with tripe backquotes and have implicit
/// 'fn main()' inside and 'extern crate <createname>'.
/// So, for our example that will be 'my_libs' (look at Cargo.toml)
///
/// ```
/// let result = my_libs::sub::substract(35, 34);     <--- testy corner casy jak to dziala
/// assert_eq!(result, 1);
/// ```
///
pub fn substract(a: i32, b: i32) -> i32 {
    a - b
}
cargo test --doc -p my_libs

Iterferencja typow - jest w stanie wywnioskowac typ primityvwe_types.rs

let mut result = add(34, 35);

let x = 1234;

let y: i32 = 1234;  //integer
let z: u32 = 1234;  //unsign integer
cargo run --bin primitive_types
rustc --explain E0277

Funkcja pomocnicza do wypisania typu

fn print_type<T>(_: &T) {
    println!("{}", type_name::<T>());
}
  • typy i8,i16,i32,i64,i128
  • typy u8,u16,u32,u64,u128
  • zmienopozycyjne f32,f64

jakie defaultowe wartosci przypisuje

Stringi formatujace

    println!("robot_check: {}", robot_check);
    println!("robot_check: {:.20}", robot_check);   --20 miejsc po przecinku
Typy znakowe

kodowane jako utf8 4bajty

bool type standard
unit type typ jednostkowy
let unit = ();

funkcja ktora nie zwraca niczego zwraca unit type

Dopisanie typu do wartosci

let elem = 5.0f32; -- kolejny sposob definiowana typow let f32 elem = 5.0;
ptzydatne dla tego ponizej
let elem = {
if x<2 {
5.0f32
} else {
6.0f64
}
}

vector odpowiednik listy w pythoniew

           ptr      len  capacity
       +--------+--------+--------+
       | 0x0123 |      2 |      4 |
       +--------+--------+--------+
            |
            v
Heap   +--------+--------+--------+--------+
       |    'a' |    'b' | uninit | uninit |
       +--------+--------+--------+--------+
let elem = 5.0f32;
let mut vec = Vec::new();  // Empty vector (growable array)
vec.push(elem); // Try commenting this line
println!("{:?}", vec);
println!("{:?}", vec_as_ptr);

dodajac pierwszy element definjujemy typ vectora dane vectora londuja na heap

cargo run --bin types_continued
 println!("{}", vec);
   |               --   ^^^ `Vec<f32>` cannot be formatted with the default formatter
   |               |
   |               required by this formatting parameter
   |
   = help: the trait `std::fmt::Display` is not implemented for `Vec<f32>`

shadowing

wykorzystywanie tej samej nazwy a nie aliasowanie czy nadpisywanie

 // Shadowing
    let some_variable = 1;

    {
        println!("{}", some_variable);

        let some_variable = "abc";

        println!("{:?}", some_variable);
    }
    println!("{:?}", some_variable);

    let some_variable = 3;

    println!("{:?}", some_variable);

Aliasing

  • okreslanie czesci pamiecie jako inna nazwa

  • dla typow prymitywnych jest to kopia

  • wiele mutowalnych borowo i nic wiecej

  • albo jeden mutowalny

W rust mamy zmienna jezeli sa jakies dane to tzw barrow - pozyczenie czyli jakas zmienna moze byc niemutowalnie pozyczana ile razy chcemy Ale jesli mamy choc jedno takie pozyczenie to niemozemy stworzyc pozyczenia mutowalnego

// Aliasing
// 1. Data can be immutably borrowed any number of times, but while that
// 1a. It cannot be mutably borrowed.
// 2. Only ONE mutable borrow is allowed at a time.
// Original value can be borrowed again
  • barrow checker

unsafe

unsafe {

}
wewnatrz barow checket nie dziala



DMA - hardware - pisanie do pamieci bezposrednio to unsafe

let mut point = Point {x: 0, y: 1, z: 2};

let borrowed_point = &point; let another_borrow = &point;

println!("Point has coordinates --> {} {} {}", borrowed_point.x, another_borrow.y, point.z);


let mut point = Point {x: 0, y: 1, z: 2};

let borrowed_point = &point;
let another_borrow = &point;

println!("Point has coordinates --> {} {} {}", borrowed_point.x, another_borrow.y, point.z);

//let mutable_borrow = &mut point; // Uncomment

println!("Point has coordinates --> {} {} {}", borrowed_point.x, another_borrow.y, point.z);

let mutable_borrow = &mut point;

* to pierwsze mutowane zakomentowane nie mozemy zrobic bo po tym uzywamy pozyczonej wartosci println!("Point has coordinates --> {} {} {}", borrowed_point.x, another_borrow.y, point.z);
* to drugie mutowane bo pozyczona zmienna niemutowalnie juz nie jest wykorzystywana i kompilator o tym wie i pozwala mutowalna zrobic


#### Rzutowanie
* https://doc.rust-lang.org/std/keyword.as.html
* https://doc.rust-lang.org/reference/
* as to slowo kluczowe
* Nie ma inplicit casting jak w C

// Casting let decimal = 21.37_f32;

// let integer: u8 = decimal; // NO IMPLICIT CASTING!
// Uncomment ^

let integer = decimal as u8;

println!("Casting: {} -> {}", decimal, integer);

println!("1000 as u16: {}", 1000 as u16);
println!("1000 as u8:  {}", 1000 as u8); // Check "allow" attribute // Comment to see what
                                         // happens
println!("-1 as u8:    {}", (-1i8) as u8);

Casting: 21.37 -> 21 1000 as u16: 1000 1000 as u8: 232 - zwrocil reszte -1 as u8: 255


#### przypisanie z expresion - blok kodu

let zmienna = {

}

wyrazenia czyli rvalue ktore zwroci i przypisze do zmiennej lvalue


void w C typem ktory nic nie zawiera a w rust jest unit type ktory zawiera jedna wartosc ale czysty abstrac

#### Typy zlozone
* struktury
* kolekcje krotki(tuple),listy

Idiom wyswietla typ jak nie jestesmy pewni jaki jest

print_type(&some_tuple_1);


Idiom `_` zignoruj

(,,trzeci) = funkcja_zwrac_trzy_wartosci();


wypisywane zagniezdzone `:?`

println!("{:?}", tablica);

#### Tablice
* https://doc.rust-lang.org/std/primitive.array.html
* typ prymitywny

let tablica: [u8; 4] = [0xCA, 0xFE, 0xBA, 0xBE]; print_type(&tablica); println!("{:?}", tablica);

println!("{}", tablica[2]);
println!("{}", tablica[3]);

[u8; 4] [202, 254, 186, 190] 186 190


##### iter

print!("0x"); for val in tablica.iter() { print!("{:X}", val); } println!();

na iteratorze jest metoda next ktora zwraca typ optional

let zeros_array: [u8; 256] = [0; 256]; println!("{:?}", zeros_array); println!("Size of zeros_array: {}", size_of_val(&zeros_array)); println!("Length of zeros_array: {}", zeros_array.len());


defaultowo rust uzywa  int32 ale float64

w adresacji 64 bit wykorzystywane jest 48 bitow. I tak javascript uzywa tylko 48 i gdy bedzie wykorzystywac wszystkie to javascript przestanie dzialac

let zeros_array: [u8; 256] = [0; 256]; //wpisz 256 razy zero println!("{:?}", zeros_array); println!("Size of zeros_array: {}", size_of_val(&zeros_array)); println!("Length of zeros_array: {}", zeros_array.len());


Niezainicjowana tablice da ale jako unsafe

unsafe { let buff_zero=[u128;4]; 4 wartosci u128 }


#### Slice
w python,go i jest tez cos w c++
w c++ jest manifest memory safety w c++ - presja rust-a

// Panic example - also RUST_BACKTRACE let x = vec![1, 2, 3]; let _ = &x[4..4];


Makro vec![1, 2, 3] makro kture pushuje wartosc zamiast  Vec::new()

### Stringi
* https://doc.rust-lang.org/std/string/struct.String.html
* stringi maja wspaznik i alokowane na heap. Lifetime aby byl statyczny musi byc na heapie a zmiennna  to fat pointer do tego miejsca
* rustowe stringi to nie null terminated stringi - wskaznik na poczatek i dlugosc

let y: &str = "Hello!";

let mut something = "Hello!"; something = "Żółć!";


* https://doc.rust-lang.org/std/keyword.unsafe.html

let s = unsafe { // First, we build a &[u8]... let slice = slice::from_raw_parts(story.as_ptr(), story.len());

    // ... and then convert that slice into a string slice
    str::from_utf8(slice)
};
#### Trait Size
* https://doc.rust-lang.org/std/marker/trait.Sized.html


let s = unsafe { // First, we build a &[u8]... let slice = slice::from_raw_parts(story.as_ptr(), story.len());

    // ... and then convert that slice into a string slice
    str::from_utf8(slice)
};
assert_eq!(s, Ok(story));

println!("story: {}", story);
print_type(&story);
println!("s: {:?}", s);
print_type(&s);
println!();
Reult - typ generyczny ktory zawiaera w sobie typ - laczy swiat safe i unsafe
* https://doc.rust-lang.org/std/result/

unwrap czesto sie przydaje. Funkcje w C typu scdf uzywamy w rust to zwroca result i tego resulta mozna zrobic unwrap czyli stwierdzamy ze jest ok. Wyciaganie wartosci z ok ale co jesli byl error
unwrap zwraca wartosc

println!("s: {:?}", s); println!("s: {:?}", s.unwrap); s: Ok("Once upon a time...") -- bez unwrapa s:"Once upon a time..." - to co zwraca z unwrap czyli wes okejke z resulta i ja zwroc

match

let story = "Once upon a time...";
let s = unsafe {
        // First, we build a &[u8]...
        let slice = slice::from_raw_parts(story.as_ptr(), story.len());

        // ... and then convert that slice into a string slice
        str::from_utf8(slice)
    };
assert_eq!(s, Ok(story));

String to nie wektor charow

let pangram: &'static str = "pchnąć w tę łódź jeża lub ośm skrzyń fig";
    println!("Polski pangram: {}", pangram);

    let mut chars: Vec<char> = pangram.chars().collect();
    // chars.sort().dedup(); // Uncomment and check error
    chars.sort();
    chars.dedup();
let mut polski_string = String::new();
for c in chars {
        polski_string.push(c);
    }
    println!("Posortowane: {}", &polski_string); 

Sortowanie poprawnie w jezyku polskim to zdefiniowac funkcje sort. Normalnie znaki narodowe na koncu wypisuje przy sortowaniu

Posortowane:  abcdefghijklmnoprstuwyzóąćęłńśźż
 // Alokacja na stercie
    let psiarze = String::from("Kocham pieski!");
    // Nowa alokacja ze zmienionym stringiem
    let kociarze: String = psiarze.replace("pieski", "kotki"); czyli operacje na stringach tworza nowy obiekt a nie robi w miejscu

    println!("Psiarze mówią: {}", psiarze);
    println!("{:?}", psiarze.as_ptr());
    println!("Kociarze mówią: {}", kociarze);
    println!("{:?}", kociarze.as_ptr());

W dokumentacji jest tez eksperymentalne api

This is a nightly-only experimental API. (string_from_utf8_lossy_owned [#129436](https://github.com/rust-lang/rust/issues/129436))

https://doc.rust-lang.org/std/string/struct.String.html#trait-implementations - co kompilator bedzie robil z naszym typem

w rust nie mamy klas i obiektow ale podobne konstrukty typu trait

Paterm matching

#![allow(unreachable_code, unused_labels)]

Labalowane petle

'outer: loop {
        println!("Entering outer loop");
        'inner: loop {
            println!("Entering the inner loop");
            
            break 'outer;
        }
        println!("Unreachable code");
    }

if/ else bez nawiasow w warunku

 if n < 0 {
        println!("N jest negatywne");
    } else if n > 0 {
        println!("N jest pozytywne");
    } else {
        println!("N to zero :O");
    }

Warunek ktory blok kodu odpalic

let big_n = if n < -100 && n > 100 {
        println!("N jest super mocno negatywne :(");
        n * 100
    } else {
        println!("N jest super mocno pozytywne! :)");
        n * 100
    }; // semicolon at the end of expression! (not statement)

return w Ruscie zanika. Ostatnie wywzenie to co zwroci to bedzie zwrocone

let result = loop {
        counter += 1;

        if counter == 68 {
            break counter + 1;
        }
    }; // Expressions need semicolon
let names = vec!["Kasia", "Mariusz", "Janusz", "Ferris"];
for name in names.iter() {
        match name {
            &"Ferris" => println!("Znaleziono dzikiego Ferrisa!"),
            // "Ferris" => println!("Znaleziono dzikiego Ferrisa!"),
            // Switch above statements to see what'll happen
            _ => println!("Hello, {}", name),
        }
    }
    println!("names: {:?}", names);

    // Lets consume the collection
    for name in names.into_iter() {
        match name {
            "Ferris" => println!("Kolejny dziki Ferris..."),
            _ => println!("Hello {}", name),
        }
    }
    println!("names: {:?}", names);
 let names = vec!["Kasia", "Mariusz", "Janusz", "Ferris"];
    |         ----- move occurs because `names` has type `Vec<&str>`, which does not implement the `Copy` trait
...
122 |     for name in names.into_iter() {
    |                       ----------- `names` moved due to this method call
...
129 |     println!("names: {:?}", names);
    |                             ^^^^^ value borrowed here after move
    |
note: `into_iter` takes ownership of the receiver `self`, which moves `names`

name.iter vs names.into_iter robimy to samo

*name - dereferencja. Referencja nie jest adresem
let names = vec!["Kasia", "Mariusz", "Janusz", "Ferris"];
for *name in names.iter() {
        match name {
            //&"Ferris" => println!("Znaleziono dzikiego Ferrisa!"),
            "Ferris" => println!("Znaleziono dzikiego Ferrisa!"),
            // Switch above statements to see what'll happen
            _ => println!("Hello, {}", name),
        }
    }

lest x = 'Hello'; static string *x - daje referencje mutowalna

  • znacza ze wyciagamy wartosc - chodzi o referencje mutowalne - typowo rustowa rzecz
// Lets modify the collection in place
    let mut samochody = ["Toyota", "Ford", "Nissan", "Tesla", "Polonez"];

    println!("samochody: {:?}", samochody);

    for samochód in samochody.iter_mut() {
        *samochód = match samochód {
            &mut "Polonez" => "Duma polskiej motoryzacji!",
            _ => "Jakieś auto ugh.",
        }
    }

    println!("samochody: {:?}", samochody);

*samochod - mozna to wytlumaczyc jako mutowanly dostep Dereferencja pobiera wartosc stringa a samo samochod jako adres w pamieci dzie jest przechowywany. Mozna to interpretowac jakao dereferensowac adreay

3 sposoby iterowania iter, into_iter, iter_mut

Metoda Zwracany typ Co robi Lazy?
.iter() Iter<'_, T> Iteruje po referencjach do elementów ✅ Tak
.iter_mut() IterMut<'_, T> Iteruje po mutowalnych referencjach ✅ Tak
.into_iter() IntoIter Zużywa kolekcję i zwraca wartości ✅ Tak

Matchowanie po wartosci

// match
    let liczba = 13;
    // let liczba = 123;

    match liczba {
        13 => println!("Trzynastka!"),
        2 | 3 | 5 | 7 | 11 => println!("Liczba pierwsza"),
        _ => println!("W sumie to nie wiem"),
    }
// match
    let liczba = 13;
    // let liczba = 123;

    match liczba {
        13 => println!("Trzynastka!"),
        2 | 3 | 5 | 7 | 11 => println!("Liczba pierwsza"),
        _ => println!("W sumie to nie wiem"),
    }

Destrukturyzowanie wartosci

vMachowanie po kolekcjach tuple(krotka)
let triple = (0, -2, 3);
    // TODO ^ Try different values for `triple`

    println!("Tell me about {:?}", triple);
    // Match can be used to destructure a tuple
    match triple {
        // Destructure the second and third elements
        (0, y, z) => println!("First is `0`, `y` is {:?}, and `z` is {:?}", y, z),
        (1, ..)  => println!("First is `1` and the rest doesn't matter"),
        (.., 2)  => println!("last is `2` and the rest doesn't matter"),
        (3, .., 4)  => println!("First is `3`, last is `4`, and the rest doesn't matter"),
        // `..` can be used to ignore the rest of the tuple
        _      => println!("It doesn't matter what they are"),
        // `_` means don't bind the value to a variable
    }

Dereferencing uses *

// Dereferencing uses *
    // Destructuring uses &, ref and ref mut
    let reference = &4;

    match reference {
        &val => println!("Got a value via destructuring: {:?}", val),
    }

    match *reference {
        val => println!("Got a value via dereferenginc: {:?}", val),
    }
let maybe_name = Some(String::from("Alice"));
// The variable 'maybe_name' is consumed here ...
match maybe_name {
    Some(n) => println!("Hello, {n}"),
    _ => println!("Hello, world"),
}
// ... and is now unavailable.
println!("Hello again, {}", maybe_name.unwrap_or("world".into()));
let maybe_name = Some(String::from("Alice"));
// The variable 'maybe_name' is consumed here ...
match maybe_name {
    Some( ref n) => println!("Hello, {n}"),  // !!!!! dodanie ref
    _ => println!("Hello, world"),
}
// ... and is now unavailable.
println!("Hello again, {}", maybe_name.unwrap_or("world".into()));
    let mut mut_value = 6;
    match mut_value {
        ref mut m => {
            *m += 10;
            println!("We added 10. 'mut_value': {:?}", m);
        }
    }

Problem zreferencja rozwiazujemy * albo ref

 match age() {
        0 => println!("Masz zero lat"),
        n @ 1 ..=17 => println!("Nie możesz pić piwa! masz {:?} lat", n),
        n @ 18 ..=u32::MAX => println!("Możesz pić piwo, masz już {:?} lat", n),
    }

    match some_number() {
        Some(n @ 42) => println!("The answer is: {}!", n),   // patern matchin sprawdzamy czy somw zwraca wartosc 42
        Some(n) => println!("Nudne... {}", n),               // jaka kolwiek inna
        _ => (),                                             // odpowiednik null w rust
    }

System typow jest rozbudowany sa Some,Result,Option

if let Some(i) = number {    //jezeli some jest number to wyciagnij wartosc
        println!("Matched {:?}!", i);
    }
if let Some(i) = letter {
        println!("Matched {:?}!", i);
    } else {
        // Destructure failed. Change to the failure case.
        println!("Didn't match a number. Let's go with a letter!");
    }

Rozbudowany flow z typami rust-owymi

Struc

Drop

enum

glownie uzywane w pattern matching

// Type aliasing
    type Action = EveryOperationWeCanDoOnOurWebsite;   //krotsza nazwa zamiast dluzszej

Semantyka ownershipu - jesli funkcja ma zmienne to za nie odpowiada - moze jes zdropowac,moze sklonowac

rust - thread safe takie zalozenie

enum EveryOperationWeCanDoOnOurWebsite {
    PageLoad,
    PageUnload,
    KeyPress(char),
    Paste(String),
    Click {x: i64, y: i64},
}

Stale const

Mutex - mechanizm do synchronizowania watku - sekcja krytyczna - toaleta i klucz

semafor - pociag i jeden tor

Obejscie statycznego globalnego stanu

// Approach for static mutable state
static GREETING: LazyLock<Mutex<String>> = LazyLock::new(|| Mutex::new("Hello, world!".to_string()));

let mut greeting = GREETING.lock().unwrap();
    println!("{:?}", greeting);

    *greeting = "Goodbye, cruel world!".to_string();

LazyLock - wartosc jest incjowana przy pierszej probie dostepu do wartosci

LazyCell - jednowatkowy LazyLock

Funkcje

funkcja ktora nic nie zwraca zwraca typ unit type ()

// Function taking and returning ownership
fn take_and_return_ownership_of_title(title: String) -> String {
    println!("Today we are going to read: {}", title);
    title
}
 let rust_title = create_string();
    println!("Rust book title: {}", rust_title);

    // Take - return ownership
    let new_rust_title = take_and_return_ownership_of_title(rust_title);
    println!("New rust title: {}", new_rust_title);

    // println!("Old rust title: {}", rust_title);  // Uncomment to see error
obraz

Przekwzywanie przez zmienna nie zadziala bo nie ma traita copy albo uzywac metody clone

 let rust_title = create_string();
    println!("Rust book title: {}", rust_title);

    // Take - return ownership
    let new_rust_title = take_and_return_ownership_of_title(rust_title);
    println!("New rust title: {}", new_rust_title);

    // println!("Old rust title: {}", rust_title);  // Uncomment to see error

Wprowadzajac referencje wiemy ze zmieniamy wewnatrz w tej zmiennej

// Function taking and returning ownership
fn take_and_return_ownership_of_title(title: &String) -> &String {
    println!("Today we are going to read: {}", title);
    title
}
 let rust_title = create_string();
    println!("Rust book title: {}", rust_title);

    // Take - return ownership
    let new_rust_title = take_and_return_ownership_of_title(&rust_title);
    println!("New rust title: {}", new_rust_title);

    // println!("Old rust title: {}", rust_title);  // Uncomment to see error


#### Nested function ownership

// Function takes ownership, modifies the value, and returns ownership fn modify_title(mut title: String, suffix: &str) -> String { title.push_str(suffix); title }

// Functon that modifies the value AND returns it fn process_title(title: String) -> String { let modified = modify_title(title, " 2: Electric Boogaloo"); modified }



Kompilacja w Rust trwa bardzo dlugo
* https://doc.rust-lang.org/nomicon/lifetimes.html

##### lifetiome
<'a>   &'a str  - lietime a

// Function compering two string references and returns the longest one fn longest_title<'a>(title_1: &'a str, title_2: &'a str) -> &'a str { if title_1.len() > title_2.len() { title_1 } else { title_2 } } // zwracamy pozyczona wartosc &'a ale nie wiemy ktora



jak zrobiles move to nie rob po funkcji juz nie uzywaj
jak mammy barrow

<img width="973" height="595" alt="obraz" src="https://github.com/user-attachments/assets/c04e3fe3-cb30-4491-9288-c63d6291b303" />

fn longest_title<'a>(title_1: &'a str, title_2: &'a str) -> &'a str { if title_1.len() > title_2.len() { title_1 } else { title_2 } }

funkcja i parametry maja ten sam czas zycia

* https://doc.rust-lang.org/nomicon/lifetime-elision.html


let rust_title = create_string(); println!("Rust book title: {}", rust_title);

// Take - return ownership
let new_rust_title = take_and_return_ownership_of_title(rust_title);  // new_rust_title tworzone jest ale rust_title jest usuwanie dlaczego print rust_title bedzie bledem
println!("New rust title: {}", new_rust_title);

// println!("Old rust title: {}", rust_title);  // Uncomment to see error

##### Closures
* Zdefiniowana funkcja ktora przejmuje do swojego srodka zdefiniowane wartosci z zewnatrz
* domkniecie definjuje sie:  `|cena: i32, tytuł: String|`
* zamykanie zmiennych funkcji - przypomina obiekty

// Closures let marża_sprzedawcy = 5; let książka_z_ceną = |cena: i32, tytuł: String| println!("Książka {:?} kosztuje {}", tytuł, cena + marża_sprzedawcy);

let marża_sprzedawcy = 10;

książka_z_ceną(42, novel_ref.to_string());

#### Higher Ordered Funcions
* Funkcje zwracac lub jako argumenty . W C namiastki przez wskazniki na funkcje
* hof.rs w przykladach

fn apply_to_all(f: F, data: Vec) -> Vec where F: Fn(i32) -> i32, // F is type parameter - function taking i32 and returning i32 { data.into_iter().map(f).collect() }

* where
* Fn z duzej f

czym sie rozni copy od clone


fn make_adder(x: i32) -> impl Fn(i32) -> i32 { move |y| x + y // Comment to check error - move creates a closure and returns it }

funkcja zwraca funkcj - slowo kluczowe `move` 

* https://doc.rust-lang.org/book/ch13-01-closures.html
* https://doc.rust-lang.org/std/keyword.move.html


* https://github.com/mre/idiomatic-rust

##### Scopes
scopes.rs


partial moves

// --> partial moves

#[derive(Debug)]
struct Person {
    name: String,
    age: Box<u8>,
}

let person = Person {
    name: String::from("Alice"),
    age: Box::new(21),
};

let Person { name, ref age } = person; //czesciowe przeniesienie tylko name bo age przez referencja

println!("The person's age is {}", age);

println!("The person's name is {}", name);

// println!("The person struct is {:?}", person); // Uncomment

println!("The person's age from person struct is {}", person.age);

// Borrowing --> moved to borrow.rs
// Lifetimes --> moved to lifetimes.rs
#### Borrow
przeniesienie - zmienna bieze zmiennna ale juz po nie jej nie mam
Jesli referencja to po funkcji zmienna istnieje

#### Lifetimes

fn longest(x: &str, y: &str) -> &str { if x.len() > y.len() { x } else { y }

}

// fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { // if x.len() > y.len() { x } else { y } // // }

// fn longest<'a>(x: &str, y: &str) -> &'a str { // let result = String::from("really long string"); // result.as_str() // }

fn main() { println!("Lifetimes - example.");

let i = 3;
{
    let borrow1 = &i;

    println!("borrow1: {}", borrow1);
}

{
    let borrow2 = &i;

    println!("borrow2: {}", borrow2);

}
// foo<'a>
// foo<'a, 'b> <-- lifetime of foo cannot exceed that of either 'a or 'b

let string1 = String::from("long string is long and longer even");
let result;
{
    let string2 = String::from("xyz");
    result = longest(string1.as_str(), string2.as_str());
}

// println!("The longest string is {result}"); // Uncomment

}

* https://doc.rust-lang.org/std/string/struct.String.html#method.as_str

ezoteryczny - magiczny zadko spotykany tajemniczy dla wiekszosci

// fn longest<'a>(x: &str, y: &str) -> &'a str { // let result = String::from("really long string"); //niby jest tworzone na heap wiec po wyjsciu z funkcji powinno byc ale rust nie pozwala tego zwrocic bo jest niszczone // result.as_str() // }

resutt probujemy zwrocic jako referencje a ono jest niszczone powyjsciu z funkcji bo tam jest tworzona


fn longest(x: &str, y: &str) -> &str {
  if x.len() > y.len() { x } else { y }
}

// foo<'a>
// foo<'a, 'b> <-- lifetime of foo cannot exceed that of either 'a or 'b

let string1 = String::from("long string is long and longer even");
let result;
{
    let string2 = String::from("xyz");
    result = longest(string1.as_str(), string2.as_str());
}

// println!("The longest string is {result}"); // Uncomment

pozyczenie,przeniesienia,przekazywania - to sedno rust
bezpieczenstwo wymuszone na poziomie analizy statycznej

wiele rzeczy dzieje sie pod spodem w rusrt

llm-y

ffi - zewnetrzne funkcje z C 
https://doc.rust-lang.org/rust-by-example/std_misc/ffi.html
https://doc.rust-lang.org/nomicon/ffi.html

Biblioteki:
* [iced.rs](https://iced.rs/) A cross-platform GUI library for Rust focused on simplicity and type-safety.
* egui [GitHub - emilk/egui: egui: an easy-to-use immediate mode GUI in Rust that runs on both web and native](https://github.com/emilk/egui)
* [actx.rs](https://actix.rs/) - backend asynchroniczny web
* [tokyo](https://lib.rs/crates/tokio)  backend asynchroniczny web

lib.rs - strona z wieloma bibliotekami rustoowymi

amd - kompilator fortrana

[ripgrep](https://github.com/BurntSushi/ripgrep) - szybki grep

pingora cloudflare w rust

https://github.com/ragnarlodbrok1992/rust-szkolenie-2025/pull/1
⚠️ **GitHub.com Fallback** ⚠️