# Ok, ok(), is_ok(), () — rýchlokurz --- ## 1. Dva svety: Result a Option ``` Result → Ok(hodnota) alebo Err(chyba) Option → Some(hodnota) alebo None ``` Result používaš keď chceš vedieť ČO sa pokazilo. Option keď ťa zaujíma len či niečo existuje alebo nie. --- ## 2. Čo je () `()` je "unit type" — prázdna hodnota. Znamená "nič zaujímavé". ```rust // Funkcia, ktorá nič nevracia, v skutočnosti vracia () fn pozdrav() { println!("ahoj"); } // je to isté ako: fn pozdrav() -> () { println!("ahoj"); } ``` --- ## 3. Ok(()) — úspech bez hodnoty Keď metóda buď uspeje (ale nemá čo vrátiť) alebo zlyhá: ```rust fn pridaj_knihu(&mut self, kniha: Kniha) -> Result<(), ()> { if self.knihy.iter().any(|k| k.nazov == kniha.nazov) { return Err(()); // zlyhalo — duplikát } self.knihy.push(kniha); Ok(()) // úspech — ale nemám čo vrátiť, tak () } ``` `Ok(())` = "podarilo sa, nemám ti čo dať". `Err(())` = "nepodarilo sa, a ani ti nepoviem prečo". ### Kedy Result<(), ()> Keď nepotrebuješ ani návratovú hodnotu ani detail chyby: ```rust fn pridaj(&mut self, meno: &str) -> Result<(), ()> { ... } fn nastav(&mut self, hodnota: u32) -> Result<(), ()> { ... } ``` ### Kedy Result Keď pri úspechu vraciaš niečo, ale chyba nemá detail: ```rust fn odstran(&mut self, meno: &str) -> Result { ... } // Ok(kniha) — tu je odstránená kniha // Err(()) — nenašiel som ju ``` ### Kedy Result Keď chceš popísať chybu: ```rust fn pridaj(&mut self, kniha: Kniha) -> Result<(), String> { if self.knihy.iter().any(|k| k.nazov == kniha.nazov) { return Err(format!("Kniha '{}' už existuje", kniha.nazov)); } self.knihy.push(kniha); Ok(()) } ``` --- ## 4. .ok() — Result → Option (zahoď chybu) `.ok()` premení Result na Option. Ak bol Err, zahodí chybu a dá None: ```rust Result → .ok() → Option Ok(42) → .ok() → Some(42) Err("chyba") → .ok() → None ``` ```rust // Prakticky: let cislo: Result = "42".parse(); let cislo: Option = "42".parse().ok(); // Some(42) let cislo: Option = "abc".parse().ok(); // None // Súborový I/O: let obsah: Result = fs::read_to_string("data.json"); let obsah: Option = fs::read_to_string("data.json").ok(); ``` **Kedy:** Keď ťa nezaujíma detail chyby, len či sa podarilo. --- ## 5. .ok()? — najčastejší vzor na skúške `.ok()` + `?` spolu — premení Result na Option a ak je None, vráti None z funkcie: ```rust fn nacitaj_zo_suboru(cesta: &PathBuf) -> Option { let raw = fs::read_to_string(cesta).ok()?; // ^^^^^^^^^^^^^^^^^^^^^^^^^ Result // .ok() → Option // ? → ak None, return None; ak Some, rozbaľ serde_json::from_str(&raw).ok() // ^^^ posledný riadok — .ok() premení na Option, vráti sa } ``` Rozklad: ``` Súbor existuje: fs::read_to_string → Ok("{ ... }") .ok() → Some("{ ... }") ? → "{ ... }" (rozbalí Some) serde_json::from_str → Ok(Kniznica{...}) .ok() → Some(Kniznica{...}) → funkcia vráti Some(Kniznica{...}) Súbor neexistuje: fs::read_to_string → Err(io::Error) .ok() → None ? → return None (okamžite opustí funkciu) ``` --- ## 6. .is_ok() a .is_err() — bool kontrola ```rust let vysledok: Result = Ok(42); vysledok.is_ok() // true vysledok.is_err() // false let vysledok: Result = Err("chyba".into()); vysledok.is_ok() // false vysledok.is_err() // true ``` **Hlavné použitie — ukladanie:** ```rust fn uloz_do_suboru(&self, cesta: &PathBuf) -> bool { let Ok(json) = serde_json::to_string_pretty(&self) else { return false; }; fs::write(cesta, json).is_ok() // ^^^^^^ Result → bool // úspech → true, chyba → false } ``` `fs::write` vracia `Result<(), Error>`. Nás zaujíma len "podarilo sa?" → `.is_ok()` dá `bool`. --- ## 7. .ok_or() a .ok_or_else() — Option → Result Opačný smer: máš Option, chceš Result. ```rust Option → .ok_or(chyba) → Result Some(42) → .ok_or("nič") → Ok(42) None → .ok_or("nič") → Err("nič") ``` ```rust // Prakticky — position vracia Option, ty chceš Result fn odstran(&mut self, meno: &str) -> Result { let pos = self.mena.iter().position(|m| m == meno).ok_or(())?; // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Option // .ok_or(()) → Result // ? → ak Err, return Err Ok(self.mena.remove(pos)) } ``` ```rust // ok_or_else — lazy verzia (closure sa zavolá len ak None) fn najdi(&self, meno: &str) -> Result<&Kniha, String> { self.knihy.iter() .find(|k| k.nazov == meno) .ok_or_else(|| format!("Kniha '{}' nenájdená", meno)) } ``` --- ## 8. .unwrap_or() a .unwrap_or_default() — fallback hodnota ```rust // Option let cislo: Option = None; cislo.unwrap_or(0) // 0 — fallback cislo.unwrap_or_default() // 0 — default pre i32 // Result let cislo: Result = "abc".parse(); cislo.unwrap_or(0) // 0 — fallback cislo.unwrap_or_default() // 0 // Na skúške — načítanie s fallbackom let kniznica = Kniznica::nacitaj_zo_suboru(&cesta) // Option .unwrap_or_default(); // Kniznica::default() ak None ``` --- ## 9. let...else — rozbaľ alebo odíď ```rust // Ak je Ok, rozbaľ do premennej. Ak Err, vykonaj blok (musí divergovať — return/break/continue). let Ok(json) = serde_json::to_string_pretty(&self) else { return false; }; // tu json je String // Ak je Some, rozbaľ. Ak None, odíď. let Some(kniha) = self.knihy.iter().find(|k| k.nazov == nazov) else { return None; }; // tu kniha je &Kniha ``` --- ## 10. Veľký prehľad: čo kedy ### Mám Result, chcem... | Chcem | Použi | Príklad | |-------|-------|---------| | Option (zahodiť chybu) | `.ok()` | `"42".parse().ok()` → `Some(42)` | | bool (podarilo sa?) | `.is_ok()` | `fs::write(c, d).is_ok()` → `true` | | Rozbaľ alebo vráť None | `.ok()?` | `fs::read_to_string(c).ok()?` | | Rozbaľ alebo panic | `.unwrap()` | len v testoch! | | Rozbaľ alebo fallback | `.unwrap_or(val)` | `vstup.parse().unwrap_or(0)` | | Rozbaľ alebo default | `.unwrap_or_default()` | `nacitaj().unwrap_or_default()` | | Rozbaľ alebo return | `let Ok(x) = ... else { return }` | serializácia v uloz | ### Mám Option, chcem... | Chcem | Použi | Príklad | |-------|-------|---------| | Result (pridať chybu) | `.ok_or(err)` | `vec.find(x).ok_or(())` | | Rozbaľ alebo vráť None | `?` | `slovnik.get(kat)?` | | bool (existuje?) | `.is_some()` / `.is_none()` | `mapa.get("x").is_some()` | | Rozbaľ alebo fallback | `.unwrap_or(val)` | `mapa.get("x").unwrap_or(&0)` | | Rozbaľ alebo default | `.unwrap_or_default()` | `nacitaj().unwrap_or_default()` | | Rozbaľ alebo return | `let Some(x) = ... else { return }` | | ### Chcem vrátiť z funkcie... | Návratový typ | Úspech | Zlyhanie | |---------------|--------|----------| | `Result<(), ()>` | `Ok(())` | `Err(())` | | `Result` | `Ok(hodnota)` | `Err(())` | | `Result<(), String>` | `Ok(())` | `Err("popis".into())` | | `Result` | `Ok(hodnota)` | `Err(format!("..."))` | | `Option` | `Some(hodnota)` | `None` | | `bool` | `true` | `false` | ### Konverzie — kompletná mapa ``` Result ──.ok()──────→ Option (zahodí E) Result ──.is_ok()───→ bool Result ──.is_err()──→ bool Option ──.ok_or(e)─────→ Result (pridá E) Option ──.is_some()────→ bool Option ──.is_none()────→ bool Result ──.unwrap_or(val)────→ T Option ──.unwrap_or(val)────→ T Result ──.unwrap_or_default()──→ T (T: Default) Option ──.unwrap_or_default()──→ T (T: Default) ```