PV281: Programování v Rustu1/82 Obsah Organizační informace Hodnocení předmětu Co za semestr probereme? O Rustu a jeho historii Úvod do Rustu a jeho syntaxe Základní typy a řízení toku programu 2/82 Organizační informace 3/82 Interaktivní osnova Primárním zdrojem informací během semestru je předmětová Interaktivní osnova. 4/82 Přednášky 2h týdně, vždy v pondělí v 18–20 hod. Přednášející: Lukáš Grolig, Stanislav Zeman, Marek Mišík, Marek Vrbka, Tomáš Sedláček, Adam Valt Během přednášky projdeme teorii a základní příklady. 5/82 Přednášky záznamy přednášek nejsou standardně dostupné. 6/82 Stream přednášek pouze po předchozím oznámení na YT nebo Twitchi. 7/82 Cvičení 2h týdně, celkem 12 cvičení Cvičící: Petr Wehrenberg, Marek Mišík, Ondřej Hrdlička, Marek Vrbka, Petr Kadlec, Lukáš Chudíček, Miloš Hegr, Otakar Hirš Na cvičení si zopakujete probranou látku a budete vypracovávat příklady s pomocí cvičících. 8/82 Poděkování Ondrovi Hrdličkovi a ostatním za pomoc s organizací předmětu. 9/82 Organizační informace, diskuze k Rustu, pomoc s úkoly či projekty, hledání týmu, ... https://discord.gg/8yvsZu9ej4 10/82 Hodnocení 11/82 Hodnocení předmětu Maximum bodů: 100 Minimum pro úspěšné zakončení předmětu: 75 12/82 Hodnocení Cvičení Možnost získat bonusové body Účast není povinná, ALE za aktivní účast získáte možnost opravit si odevzdání iterace (toto pravidlo platí od 3. týdne semestru včetně) 13/82 Hodnocení Iterace Celkem 10 iterací Každá za maximálně 5 bodů Každá z nich vás seznámí s konktrétní funkcionalitou Rustu Většinou automaticky testované, opravující kontroluje kvalitu kódu V základu máte 1 pokus na odevzdání Po code review můžete, ale nemusíte využít možnost opravy získanou na základě aktivní účasti na cvičení 14/82 Hodnocení Týmový projekt 50 bodů za týmový projekt zakončený obhajobou ve zkouškovém 4členné, výjimečně 3členné týmy – nikdy ne méně ani ne více Týmy lze vytvářet napříč seminárními skupinami. Složení týmu lze měnit do 10. týdne semestru (včetně). Zadání projektu jsou volná, očekáváme kreativitu týmu při vlastním dodefinování zadání. Zadání plánujeme zveřejnit ve 3. týdnu semestru. 15/82 Hodnocení Bonusové body Na přednášce za aktivitu Na cvičeních za aktivitu Za dobrovolné, bonusové podčásti iterací Za špičkové zpracování úkolů/projektu a výrazné překročení rozsahu 16/82 Očekávané znalosti? programování v C, programovaní v managovaném jazyce (C# nebo Java), programování ve funkcionálním jazyce práce s databází - aktivní znalost SQL a návrhu databáze základní znalosti kolem REST rozhraní - endpointy, entity, znalost HTTP znalost webobých technologií na úrovni PB138 17/82 Co za semestr probereme? 18/82 Probíraná látka Úvod - historie, hlavní (ne)výhody Rustu, založení projektu Syntaxe jazyka a jeho specifika CLI aplikace a práce se soubory, obsluha chybových stavů Iterátory a datové struktury Paralelní programování, strukturování projektu Asynchronní programování 19/82 Probíraná látka Práce s databází RESTové služby v Actix Server-side aplikace v Actix a HTMX Desktopové aplikace v Tauri gRPC protokol Unsafe Rust, makra a foreign function interface 20/82 Probíraná látka mimo Rust Budeme hodně pracovat s Gitem a GitLabem Budeme psát čisté SQL 21/82 Studijní materiály Web The Rust Programming Language Rust By Example Literatura Programming Rust: Fast, Safe Systems Development, 2nd Edition Pokročilá literatura Rust for Rustaceans: Idiomatic Programming for Experienced Developers 22/82 O Rustu a jeho historii 23/82 Seznamte se: Krab Ferris 24/82 Historie Rust vznikl v Mozille Cílem bylo vytvořit jazyk bez garbage kolekce s bezpečnou prací s pamětí 25/82 70% bezpečnostních děr v Microsoftu bylo spojených s prací s pamětí. https://msrc-blog.microsoft.com/2019/07/16/a-proactive- approach-to-more-secure-code/ 26/82 Rust Foundation Mozilla ale dál nezvládala sama rozvíjet Rust. To vedlo ke vzniku Rust Foundation v roce 2020. Zakládajícími členy se stali: 27/82 Další známé firmy využívající Rust Tento seznam se už hodně natáhl, ale můžeme jmenovat: 1Password, Apple, Canonical, Cloudflare, Discord, Dropbox, Figma, Facebook, System76, OVH 28/82 Hlavní výhody Rustu Bezpečnost V jazycích typu C vznikají problémy s manuální správou pamětí jako dangling pointer, dvojité uvolnění aj. V moderním C++ je spousta věcí řešena technikami jako je RAII nebo smartpointy. Rozdílem je, že Rustu toto nemusí nehlídat člověk, ale řeší překladač. Cenou za to je doba překladu. 29/82 30/82 Hlavní výhody Rustu Rychlost Prakticky všechny dnešní jazyky jsou pomalejší než C a C++. Je to kvůli abstrakcím, garbage kolekci aj. Výsledný program běžící v Rustu je na stejné úrovni v rychlosti běhu jako C/C++. To máme díky: zero cost abstrakci správě paměti během kompilace 31/82 1 3 5 10 30 50 100 300 CgccCgccCgccCgccCgcc g++C++g++C++g++C++g++ ustRustRustRustRustRust JuliaJuliaJuliaJuliaJulia ClassicFortranClassicFortran .NETC#.NETC#.NETC#.NET lChapelChapelChapelChapel Ada2012GNATAda2012GNAT llGHCHaskellGHCHaskellGHC ePascalFreePascalFreePascal oGoGoGoGoGoGoGo .NETF#.NETF#.NETF#.NET SwiftSwiftSwiftSwiftSwift vaJavaJavaJavaJavaJava LispSBCLLispSBCLLispSBCL 01 Mar 2023 u64qbenchmarks game programcpuseconds/lowest How many times more CPU seconds? 32/82 Srovnání Rustu s C 33/82 Srovnání Rustu s C 34/82 Porovnání frameworků ve Fortunes 35/82 Porovnání frameworků ve Fortunes 36/82 Konkurence Při paralelním programování často dochází k všemožným problémům. Rust díky síle překladače (rozumějte statickým kontrolám), pravidlům a konvencím v jazyce poskytuje podstatně větší jistotu. 37/82 Další výhody jazyk nemá dědičnost, místo toho vyžaduje kompozici neexistuje null moderní a pokrokový tooling správce závislostí dokumentování kódu testování 38/82 Nevýhody Rustu Pomalý překlad Velké množství knihoven v ekosystému stojí na jedincích Často více psaní než v jiných jazycích 39/82 Jak se rozhodovat při výběru jazyka? Potřebuju jednoúčeloový rychle naprasený tool? Python. Bude to běžet v prohlížeči nebo je to UI? JS nebo TS. Můžu použít managovaný jazyk? C# > Golang > Kotlin > Java. Jinak vyberu Rust! Rustu nahrává i lepší udržovatelnost codebase, rychlost nebo nižší chybovost kódu. 40/82 K čemu se dnes Rust primárně používá? tooly - CLI nebo integrované webové aplikace a služby knihovny pro jiné jazyky nízkoúrovňové aplikace - ovladače, jádro OS, firmware 41/82 Příběh Discordu 42/82 Příběh Discordu As usual with a garbage collected language the problem was CPU stalls due to garbage collection spikes. But in non-GC languages you have to worry about memory fragmentation, especially for long-lived processes. When you get that sev 1 bug that happens after two months of flawless execution it will often be a memory allocation failure due to memory fragmentation. So you end up creating your own memory allocator anyway. “ “ 43/82 Příběh Discordu When we started load testing, we were instantly pleased with the results. The latency of the Rust version was just as good as Go’s and had no latency spikes! Remarkably, we had only put very basic thought into optimization as the Rust version was written. Even with just basic optimization, Rust was able to outperform the hyper hand-tuned Go version. “ “ 44/82 Příběh Discordu After a bit of profiling and performance optimizations, we were able to beat Go on every single performance metric. Latency, CPU, and memory were all better in the Rust version. “ “ 45/82 Příběh Discordu Along with performance, Rust has many advantages for an engineering team. For example, its type safety and borrow checker make it very easy to refactor code as product requirements change or new learnings about the language are discovered. Also, the ecosystem and tooling are excellent and have a significant amount of momentum behind them. Also, our business case for using Go - it's all about saving money. “ “ 46/82 Příběh Discordu http://highscalability.com/blog/2020/2/7/stuff-the-internet-says- on-scalability-for-february-7th-2020.html https://blog.discord.com/why-discord-is-switching-from-go-to- rust-a190bbca2b1f 47/82 Úvod do Rustu a jeho syntaxe 48/82 Verzování Rustu nightly vydáváno každodenně beta vydávána jednou za 6 týdnů stable vydávána jednou za 6 týdnů (následujících po betě) 49/82 Problémy verzování Dříve nebyly všechny features dostupné ve stabilní verzi. Tvůrci frameworků proto sahali po nightly, a ta musela být používaná i v projektu. Dnes už to neplatí a použití nightly verze se snažíme vyhnout. Je vhodné zmínit, že Rust se rychle vyvíjí. Je proto nutné hlídat, které vlastnosti jsou deprekovány, a naopak nově přidány. 50/82 Nové verze jazyka jsou testovány na dostupných crates! 51/82 Instalace Rustu Instalaci a aktualizaci Rustu doporučujeme provádět přes rustup . UN*X curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh Windows Stáhnout rustup-init.exe a řídit se pokyny instalátoru. MacOS Pokud máte homebrew, tak brew install rustup . 52/82 Základní nástroje rustup – spravuje verze Rustu rustc – překladač cargo – balíčkovací systém, spráce projektu a závislostí clippy – linter 53/82 IDE VS Code s pluginem rust-analyzer - neinstalujte plugin jménem "Rust" (starý, deprekovaný, nahrazený) Jetbrains RustRover Jetbrains CLion s pluginem Intellij Rust 54/82 Založení nového projektu Příkazem cargo new nazev_projektu se vytvoří nový projekt: nazev_projektu +-- Cargo.toml +-- src │ +--main.rs 55/82 Překlad a spuštění cargo build cargo run 56/82 Cargo.toml [package] name = "hello_world" version = "0.1.0" edition = "2021" authors = ["Your Name "] [dependencies] rand = { git = "https://github.com/rust-lang-nursery/rand.git" } 57/82 Cargo.lock # This file is automatically @generated by Cargo. It is not intended for manual editing. [[package]] name = "hello_world" version = "0.1.0" dependencies = [ "rand", ] [[package]] name = "rand" version = "0.9.0" source = "git+https://github.com/rust-lang-nursery/rand.git#f3dd0b885c4597b9617ca79987a0dd899ab29fcb" dependencies = [ "libc", "rand_chacha", "rand_core", ] # ... 58/82 Složitější struktura projektu +-- Cargo.lock +-- Cargo.toml +-- src/ │ +-- lib.rs <----------------------------------- základní soubor knihovny │ +-- main.rs <---------------------------------- základní spustitelný soubor │ +-- bin/ <------------------------------------- veškeré další spustitelné soubory │ +-- named-executable.rs │ +-- another-executable.rs │ +-- multi-file-executable/ │ +-- main.rs │ +-- some_module.rs +-- benches/ <------------------------------------- benchmarky │ +-- large-input.rs │ +-- multi-file-bench/ │ +-- main.rs │ +-- bench_module.rs +-- examples/ <------------------------------------ ukázky kódu │ +-- simple.rs │ +-- multi-file-example/ │ +-- main.rs │ +-- ex_module.rs +-- tests/ <--------------------------------------- integrační testy +-- some-integration-tests.rs +-- multi-file-test/ +-- main.rs +-- test_module.rs 59/82 Ukázka kódu z main.rs fn main() { println!("Hello, world!"); } Všimněte si, že main nevrací hodnotu. Později zjistíte, že může vracet Result . Pro explicitní návratový kód také existuje funkce std::process::exit(code: i32) . println!() je makro. Poznáme ho podle vykřičníku. 60/82 Přidání crate pro CLI aplikace Závislost na crate clap přidáme příkazem cargo add clap . use std::path::PathBuf; use clap::{arg, command, value_parser, ArgAction, Command}; fn main() { let matches = command!() .arg(arg!([name] "Optional name to operate on")) .arg(arg!( -d --debug ... "Turn debugging information on" )) .get_matches(); // Continued on the next slide... } 61/82 Kontrola argumentů fn main() { // ...continued from the previous slide. if let Some(name) = matches.get_one::("name") { println!("Value for name: {name}"); } match matches .get_one::("debug") .expect("Count's are defaulted") { 0 => println!("Debug mode is off"), 1 => println!("Debug mode is kind of on"), 2 => println!("Debug mode is on"), _ => println!("Don't be crazy"), } } 62/82 Základní typy a řízení toku programu 63/82 Celočíselné typy Velikost Znaménkový Neznaménkový 8 bitů i8 u8 16 bitů i16 u16 32 bitů i32 u32 64 bitů i64 u64 128 bitů i128 u128 dle architektury isize usize 64/82 Zápisy literálů Velikost Příklad desítkové 98_222 šestnáctkové 0xff osmičkové 0o77 binární 0b1111_0000 bajtové b'A' 65/82 S plovoucí řádovou čárkou (IEEE-754) Velikost Typ 32 bitů f32 64 bitů f64 Výchozí je f64 . 66/82 Definice proměnné let number = 42; let number: i16 = 42i16; let mut fp_number: f64 = 3.14f64; 67/82 Boolovské typy fn main() { let t = true; let f: bool = false; } 68/82 Znakové typy (UTF-8) fn main() { let c: char = 'z'; let z = 'ℤ'; let heart_eyed_cat = ' 😻 '; } 69/82 Složené typy 70/82 Tuple (n-tice) fn main() { let tup: (i32, f64, u8) = (500, 6.4, 1); // lze použít destructuring: let (first, second) = (1, 2.0); } 71/82 Pole fn main() { let a: [i32; 5] = [1, 2, 3, 4, 5]; let first = a[0]; let second = a[1]; let months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; } 72/82 Ovládání toku programu 73/82 Klasický if fn main() { let number = 3; if number < 5 { println!("condition was true"); } else if number % 3 == 0 { println!("number is divisible by 3"); } else { println!("condition was false"); } } 74/82 If jako výraz fn main() { let condition = true; let number = if condition { 5 } else { 6 }; println!("The value of number is: {}", number); } 75/82 If let let number = Some(7); let letter: Option = None; let emoticon: Option = None; if let Some(i) = number { println!("Matched {:?}!", i); } 76/82 Match fn main() { let some_u8_value = 0u8; match some_u8_value { 1 => println!("one"), 3 => println!("three"), 5 => println!("five"), 7 => println!("seven"), _ => (), } } 77/82 Nekonečná smyčka fn main() { loop { println!("again!"); } } 78/82 While fn main() { let mut number = 3; while number != 0 { println!("{}!", number); number -= 1; } println!("LIFTOFF!!!"); } 79/82 For fn main() { for n in 1..=100 { if n % 2 == 0 { println!("even"); } else { println!("odd"); } } } 80/82 To je pro dnešek vše. Dotazy? 81/82 Děkuji za pozornost 82/82