uprava rng
This commit is contained in:
298
priprava/rust_priprava15.md
Normal file
298
priprava/rust_priprava15.md
Normal file
@@ -0,0 +1,298 @@
|
||||
# Ok, ok(), is_ok(), () — rýchlokurz
|
||||
|
||||
---
|
||||
|
||||
## 1. Dva svety: Result a Option
|
||||
|
||||
```
|
||||
Result<T, E> → Ok(hodnota) alebo Err(chyba)
|
||||
Option<T> → 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<T, ()>
|
||||
|
||||
Keď pri úspechu vraciaš niečo, ale chyba nemá detail:
|
||||
|
||||
```rust
|
||||
fn odstran(&mut self, meno: &str) -> Result<Kniha, ()> { ... }
|
||||
// Ok(kniha) — tu je odstránená kniha
|
||||
// Err(()) — nenašiel som ju
|
||||
```
|
||||
|
||||
### Kedy Result<T, String>
|
||||
|
||||
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<T, E> → .ok() → Option<T>
|
||||
|
||||
Ok(42) → .ok() → Some(42)
|
||||
Err("chyba") → .ok() → None
|
||||
```
|
||||
|
||||
```rust
|
||||
// Prakticky:
|
||||
let cislo: Result<i32, _> = "42".parse();
|
||||
let cislo: Option<i32> = "42".parse().ok(); // Some(42)
|
||||
let cislo: Option<i32> = "abc".parse().ok(); // None
|
||||
|
||||
// Súborový I/O:
|
||||
let obsah: Result<String, io::Error> = fs::read_to_string("data.json");
|
||||
let obsah: Option<String> = 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<Kniznica> {
|
||||
let raw = fs::read_to_string(cesta).ok()?;
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^ Result<String, Error>
|
||||
// .ok() → Option<String>
|
||||
// ? → 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<i32, String> = Ok(42);
|
||||
|
||||
vysledok.is_ok() // true
|
||||
vysledok.is_err() // false
|
||||
|
||||
let vysledok: Result<i32, String> = 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<T> → .ok_or(chyba) → Result<T, E>
|
||||
|
||||
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<String, ()> {
|
||||
let pos = self.mena.iter().position(|m| m == meno).ok_or(())?;
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Option<usize>
|
||||
// .ok_or(()) → Result<usize, ()>
|
||||
// ? → 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<i32> = None;
|
||||
cislo.unwrap_or(0) // 0 — fallback
|
||||
cislo.unwrap_or_default() // 0 — default pre i32
|
||||
|
||||
// Result
|
||||
let cislo: Result<i32, _> = "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<Kniznica>
|
||||
.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<T, ()>` | `Ok(hodnota)` | `Err(())` |
|
||||
| `Result<(), String>` | `Ok(())` | `Err("popis".into())` |
|
||||
| `Result<T, String>` | `Ok(hodnota)` | `Err(format!("..."))` |
|
||||
| `Option<T>` | `Some(hodnota)` | `None` |
|
||||
| `bool` | `true` | `false` |
|
||||
|
||||
### Konverzie — kompletná mapa
|
||||
|
||||
```
|
||||
Result<T, E> ──.ok()──────→ Option<T> (zahodí E)
|
||||
Result<T, E> ──.is_ok()───→ bool
|
||||
Result<T, E> ──.is_err()──→ bool
|
||||
|
||||
Option<T> ──.ok_or(e)─────→ Result<T, E> (pridá E)
|
||||
Option<T> ──.is_some()────→ bool
|
||||
Option<T> ──.is_none()────→ bool
|
||||
|
||||
Result<T, E> ──.unwrap_or(val)────→ T
|
||||
Option<T> ──.unwrap_or(val)────→ T
|
||||
|
||||
Result<T, E> ──.unwrap_or_default()──→ T (T: Default)
|
||||
Option<T> ──.unwrap_or_default()──→ T (T: Default)
|
||||
```
|
||||
Reference in New Issue
Block a user