Rust - ghdrako/doc_snipets GitHub Wiki
Documentation
Online books
Video tutorials
Blogs
- https://github.com/rust-lang/rustlings
- https://rust-exercises.com/
- https://anssipiirainen.com/post/learning-rust/
- https://github.com/LukeMathWalker
- nom - rust parser - https://github.com/rust-bakery/nom
- https://iximiuz.com/en/posts/rust-writing-parsers-with-nom/
- 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
- https://doc.rust-lang.org/book/
- https://doc.rust-lang.org/cargo/
- https://rust-lang.org/ - oficjalna strona
- https://doc.rust-lang.org/std/ - biblioteka standardowa
- https://doc.rust-lang.org/nomicon/intro.html - Rustonomicon - unsafe Rust
- https://doc.rust-lang.org/rust-by-example/ - Zestaw informacji dla poszczególnych elementów języka, dokumentacja z przykładami
- rustc - kompilator → https://doc.rust-lang.org/rustc/
- cargo - manager pakietów → https://doc.rust-lang.org/cargo/
- rust-lang.orgrust-lang.org
- Rust Programming Language A language empowering everyone to build reliable and efficient software. doc.rust-lang.orgdoc.rust-lang.org
- std - Rust The Rust Standard Library
- doc.rust-lang.orgdoc.rust-lang.org
- Introduction - The Rustonomicon The Dark Arts of Advanced and Unsafe Rust Programming doc.rust-lang.orgdoc.rust-lang.org
- Introduction - Rust By Example Rust by Example (RBE) is a collection of runnable examples that illustrate various Rust concepts and standard libraries. Bardzo dobry material !!!
Stacjait
Cargo.toml Edytion =2025 - wersja jezyka
- https://crates.io/crates/tokio - aynchroniczne operacjie i/O
- https://crates.io/
- https://lib.rs/ - z machine learning mathematic numeric np tch-rs dla pytorch
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
- https://doc.rust-lang.org/std/primitive.fn.html nie jest slowem kluczowym, jest function pointerem ale i typem. Rust posiada mozliwosc przekazywania funkcji i zwracania. Tworzenie funkcji w runtime.
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
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
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
kodowane jako utf8 4bajty
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
}
}
- przypomina std vector z c++
- https://doc.rust-lang.org/std/vec/struct.Vec.html
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>`
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);
-
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 {
}
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
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
#![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 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
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
| 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 |
// 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
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
}
- https://doc.rust-lang.org/std/keyword.ref.html
- ref annotates pattern bindings to make them borrow rather than move.
// 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
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},
}
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
- https://doc.rust-lang.org/std/sync/struct.LazyLock.html A value which is initialized on the first access.
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
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