uprava rng
This commit is contained in:
@@ -1,114 +1,110 @@
|
|||||||
# rand — krok za krokom
|
# rand — krok za krokom (aktuálna verzia)
|
||||||
|
|
||||||
Každá kapitola: prečítaj, pozri príklady, urob úlohy. Až potom choď ďalej.
|
Každá kapitola: prečítaj, pozri príklady, urob úlohy. Až potom choď ďalej.
|
||||||
|
|
||||||
`Cargo.toml`:
|
`Cargo.toml`:
|
||||||
```toml
|
```toml
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rand = "0.8"
|
rand = "0.10"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Najjednoduchší import — dáva ti všetko bežné:
|
||||||
```rust
|
```rust
|
||||||
use rand::Rng; // toto treba skoro vždy
|
use rand::prelude::*;
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Kapitola 1: Generátor náhodných čísel — thread_rng
|
## Kapitola 1: Generátor — rand::rng()
|
||||||
|
|
||||||
Všetko začína generátorom. V Ruste sa volá `thread_rng()`:
|
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Vytvor generátor
|
let mut rng = rand::rng();
|
||||||
let mut rng = rand::thread_rng();
|
|
||||||
|
|
||||||
// Náhodné i32 (celý rozsah)
|
// Náhodné celé číslo (celý rozsah typu)
|
||||||
let cislo: i32 = rng.gen();
|
let cislo: i32 = rng.random();
|
||||||
println!("{}", cislo); // napr. -1847294628
|
println!("{}", cislo);
|
||||||
|
|
||||||
// Náhodné f64 medzi 0.0 a 1.0
|
// Náhodné f64 medzi 0.0 a 1.0
|
||||||
let desatinne: f64 = rng.gen();
|
let desatinne: f64 = rng.random();
|
||||||
println!("{}", desatinne); // napr. 0.7382...
|
println!("{}", desatinne);
|
||||||
|
|
||||||
// Náhodné bool
|
// Náhodné bool
|
||||||
let minca: bool = rng.gen();
|
let minca: bool = rng.random();
|
||||||
println!("{}", minca); // true alebo false
|
println!("{}", minca);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**`mut rng`** — generátor sa mení pri každom volaní (posúva sa jeho vnútorný stav), preto musí byť `mut`.
|
`mut rng` — generátor mení svoj stav pri každom volaní.
|
||||||
|
|
||||||
### Úlohy 1
|
### Úlohy 1
|
||||||
|
|
||||||
**1a.** Vygeneruj 5 náhodných i32 čísel. Vypíš ich.
|
**1a.** Vygeneruj 5 náhodných i32 čísel. Vypíš ich.
|
||||||
|
|
||||||
**1b.** Vygeneruj 10 náhodných bool hodnôt. Spočítaj koľko bolo true a koľko false.
|
**1b.** Vygeneruj 10 náhodných bool hodnôt. Spočítaj koľko bolo true.
|
||||||
|
|
||||||
**1c.** Čo je zle?
|
**1c.** Čo je zle?
|
||||||
```rust
|
```rust
|
||||||
let rng = rand::thread_rng();
|
let rng = rand::rng();
|
||||||
let cislo: i32 = rng.gen();
|
let cislo: i32 = rng.random();
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Kapitola 2: gen_range — číslo v rozsahu
|
## Kapitola 2: random_range — číslo v rozsahu
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::rng();
|
||||||
|
|
||||||
// Celé číslo od 1 do 10 (vrátane oboch)
|
// Od 1 do 10 (vrátane oboch)
|
||||||
let cislo: i32 = rng.gen_range(1..=10);
|
let cislo: i32 = rng.random_range(1..=10);
|
||||||
|
|
||||||
// Celé číslo od 1 do 9 (10 NIE JE zahrnuté)
|
// Od 1 do 9 (10 NIE JE zahrnuté)
|
||||||
let cislo: i32 = rng.gen_range(1..10);
|
let cislo: i32 = rng.random_range(1..10);
|
||||||
|
|
||||||
// Float od 0.0 do 1.0 (1.0 nie je zahrnuté)
|
// Float od 0.0 do 1.0 (1.0 nie je zahrnuté)
|
||||||
let cislo: f64 = rng.gen_range(0.0..1.0);
|
let cislo: f64 = rng.random_range(0.0..1.0);
|
||||||
|
|
||||||
// Index do vektora
|
// Náhodný index do vektora
|
||||||
let vektor = vec!["a", "b", "c", "d", "e"];
|
let vektor = vec!["a", "b", "c", "d", "e"];
|
||||||
let index: usize = rng.gen_range(0..vektor.len());
|
let index: usize = rng.random_range(0..vektor.len());
|
||||||
let nahodny_prvok = &vektor[index];
|
let nahodny_prvok = &vektor[index];
|
||||||
```
|
```
|
||||||
|
|
||||||
**`..=`** — inclusive (vrátane konca). `..` — exclusive (bez konca).
|
|
||||||
|
|
||||||
| Zápis | Rozsah | Príklad |
|
| Zápis | Rozsah | Príklad |
|
||||||
|-------|--------|---------|
|
|-------|--------|---------|
|
||||||
| `1..10` | 1 až 9 | kocka bez 10 |
|
| `1..10` | 1 až 9 | bez konca |
|
||||||
| `1..=10` | 1 až 10 | kocka s 10 |
|
| `1..=10` | 1 až 10 | vrátane konca |
|
||||||
| `0..vektor.len()` | 0 až posledný index | náhodný index |
|
| `0..vektor.len()` | 0 až posledný index | náhodný index |
|
||||||
|
|
||||||
### Úlohy 2
|
### Úlohy 2
|
||||||
|
|
||||||
**2a.** Simuluj hod kockou (1–6). Hoď 100-krát a spočítaj koľkokrát padlo každé číslo (použi HashMap).
|
**2a.** Simuluj hod kockou (1–6). Hoď 100-krát, spočítaj výskyty každého čísla (HashMap).
|
||||||
|
|
||||||
**2b.** Vygeneruj náhodné heslo — 8 náhodných znakov z abecedy a-z. Hint: vygeneruj číslo 0..26, pripočítaj k `b'a'`, preveď na char.
|
**2b.** Vygeneruj náhodné heslo — 8 znakov a-z. Hint: `rng.random_range(b'a'..=b'z') as char`.
|
||||||
|
|
||||||
**2c.** Napíš funkciu `nahodne_cislo_v_rozsahu(od: i32, do_: i32) -> i32`. Použi `gen_range`.
|
**2c.** Napíš funkciu `nahodne_cislo(od: i32, do_: i32) -> i32`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Kapitola 3: choose — náhodný výber z kolekcie
|
## Kapitola 3: choose — náhodný výber z kolekcie
|
||||||
|
|
||||||
Toto je **najdôležitejšie** na skúške. `choose` vyberie náhodný prvok z vektora alebo slice.
|
Toto je **najdôležitejšie** na skúške.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use rand::seq::SliceRandom; // TOTO TREBA IMPORTOVAŤ!
|
use rand::seq::IndexedRandom; // TOTO TREBA!
|
||||||
|
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::rng();
|
||||||
|
|
||||||
let ovocie = vec!["jablko", "hruška", "banán", "pomaranč"];
|
let ovocie = vec!["jablko", "hruška", "banán", "pomaranč"];
|
||||||
|
|
||||||
// choose — vráti Option<&&str> (Option lebo Vec môže byť prázdny)
|
// choose — vráti Option (None ak prázdny Vec)
|
||||||
let nahodne = ovocie.choose(&mut rng);
|
let nahodne = ovocie.choose(&mut rng);
|
||||||
// Some(&"hruška") — náhodný prvok
|
// Some(&"hruška")
|
||||||
|
|
||||||
match nahodne {
|
match nahodne {
|
||||||
Some(o) => println!("Vybrané: {}", o),
|
Some(o) => println!("Vybrané: {}", o),
|
||||||
@@ -116,43 +112,26 @@ match nahodne {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Import:** `use rand::seq::SliceRandom;` — bez tohto `choose` nefunguje!
|
**Import:** `use rand::seq::IndexedRandom;` — bez tohto `choose` nefunguje!
|
||||||
|
|
||||||
|
Alebo použi `use rand::prelude::*;` — ten to zahŕňa.
|
||||||
|
|
||||||
### choose s Vec<String>
|
### choose s Vec<String>
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::IndexedRandom;
|
||||||
|
|
||||||
let slova = vec!["pes".to_string(), "mačka".to_string(), "kôň".to_string()];
|
let slova = vec!["pes".to_string(), "mačka".to_string(), "kôň".to_string()];
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::rng();
|
||||||
|
|
||||||
let nahodne: Option<&String> = slova.choose(&mut rng);
|
let nahodne: Option<&String> = slova.choose(&mut rng);
|
||||||
// Some(&"mačka")
|
// Some(&"mačka")
|
||||||
```
|
```
|
||||||
|
|
||||||
### choose s Vec<Struct>
|
|
||||||
|
|
||||||
```rust
|
|
||||||
struct Otazka {
|
|
||||||
text: String,
|
|
||||||
odpoved: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
let otazky = vec![
|
|
||||||
Otazka { text: "2+2?".into(), odpoved: "4".into() },
|
|
||||||
Otazka { text: "Hlavné mesto SR?".into(), odpoved: "Bratislava".into() },
|
|
||||||
];
|
|
||||||
|
|
||||||
let nahodna: Option<&Otazka> = otazky.choose(&mut rng);
|
|
||||||
if let Some(otazka) = nahodna {
|
|
||||||
println!("{}", otazka.text);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### choose na skúške — SpravcaHry.vytvor_novu_hru
|
### choose na skúške — SpravcaHry.vytvor_novu_hru
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::IndexedRandom;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
struct SpravcaHry {
|
struct SpravcaHry {
|
||||||
@@ -161,19 +140,19 @@ struct SpravcaHry {
|
|||||||
|
|
||||||
impl SpravcaHry {
|
impl SpravcaHry {
|
||||||
fn vytvor_novu_hru(&self, kategoria: &str) -> Option<Hra> {
|
fn vytvor_novu_hru(&self, kategoria: &str) -> Option<Hra> {
|
||||||
// 1. Nájdi kategóriu v slovníku
|
// 1. Nájdi kategóriu
|
||||||
let slova = self.slovnik.get(kategoria)?;
|
let slova = self.slovnik.get(kategoria)?;
|
||||||
|
|
||||||
// 2. Skontroluj či nie je prázdna
|
// 2. Prázdna → None
|
||||||
if slova.is_empty() {
|
if slova.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Vyber náhodné slovo
|
// 3. Vyber náhodné slovo
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::rng();
|
||||||
let slovo = slova.choose(&mut rng)?;
|
let slovo = slova.choose(&mut rng)?;
|
||||||
|
|
||||||
// 4. Vytvor hru s tým slovom
|
// 4. Vytvor hru
|
||||||
Some(Hra::new(slovo))
|
Some(Hra::new(slovo))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -181,50 +160,47 @@ impl SpravcaHry {
|
|||||||
|
|
||||||
Krok po kroku:
|
Krok po kroku:
|
||||||
```
|
```
|
||||||
slovnik = {"zvierata": ["pes", "mačka", "kôň"], "jedlo": ["pizza", "burger"]}
|
slovnik = {"zvierata": ["pes", "mačka", "kôň"]}
|
||||||
|
|
||||||
kategoria = "zvierata"
|
kategoria = "zvierata"
|
||||||
→ slovnik.get("zvierata") → Some(&["pes", "mačka", "kôň"])
|
→ slovnik.get("zvierata") → Some(&["pes", "mačka", "kôň"])
|
||||||
→ slova = &["pes", "mačka", "kôň"]
|
|
||||||
→ slova.choose(&mut rng) → Some(&"mačka")
|
→ slova.choose(&mut rng) → Some(&"mačka")
|
||||||
→ Hra::new("mačka")
|
→ Hra::new("mačka")
|
||||||
→ Some(Hra { hladane_slovo: "mačka", ... })
|
|
||||||
|
|
||||||
kategoria = "neexistuje"
|
kategoria = "neexistuje"
|
||||||
→ slovnik.get("neexistuje") → None
|
→ slovnik.get("neexistuje") → None
|
||||||
→ ? vráti None z funkcie
|
→ ? → return None
|
||||||
```
|
```
|
||||||
|
|
||||||
### Úlohy 3
|
### Úlohy 3
|
||||||
|
|
||||||
**3a.** Máš Vec mien. Vyber náhodné meno a vypíš ho.
|
**3a.** Máš Vec mien. Vyber náhodné a vypíš.
|
||||||
|
|
||||||
**3b.** Máš HashMap<String, Vec<String>> (kategória → slová). Napíš funkciu:
|
**3b.** Máš HashMap<String, Vec<String>> (kategória → slová). Napíš funkciu:
|
||||||
```rust
|
```rust
|
||||||
fn nahodne_slovo(slovnik: &HashMap<String, Vec<String>>, kategoria: &str) -> Option<&String>
|
fn nahodne_slovo(slovnik: &HashMap<String, Vec<String>>, kategoria: &str) -> Option<&String>
|
||||||
```
|
```
|
||||||
|
|
||||||
**3c.** Máš Vec<Otazka>. Vyber 5 náhodných otázok (bez opakovania). Hint: pozri kapitolu 5 (shuffle).
|
**3c.** Čo sa stane ak zavoláš `.choose()` na prázdnom vektore?
|
||||||
|
|
||||||
**3d.** Čo sa stane ak zavoláš `.choose()` na prázdnom vektore?
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Kapitola 4: choose_multiple — viac náhodných prvkov
|
## Kapitola 4: sample — viac náhodných prvkov
|
||||||
|
|
||||||
|
V novej verzii rand sa `choose_multiple` nahradil metódou `sample`:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::IndexedRandom;
|
||||||
|
|
||||||
let cisla = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
let cisla = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::rng();
|
||||||
|
|
||||||
// Vyber 3 náhodné prvky (BEZ opakovania)
|
// Vyber 3 náhodné prvky (BEZ opakovania)
|
||||||
let vybrane: Vec<&i32> = cisla.choose_multiple(&mut rng, 3).collect();
|
let vybrane: Vec<&i32> = cisla.sample(&mut rng, 3).collect();
|
||||||
// napr. [&7, &2, &9]
|
// napr. [&7, &2, &9]
|
||||||
|
|
||||||
// Ak chceš viac ako je prvkov, vráti všetky (v náhodnom poradí)
|
// Ak chceš viac ako je prvkov, vráti len toľko koľko je
|
||||||
let vsetky: Vec<&i32> = cisla.choose_multiple(&mut rng, 100).collect();
|
let vsetky: Vec<&i32> = cisla.sample(&mut rng, 100).collect();
|
||||||
// všetkých 10 prvkov v náhodnom poradí
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Na skúške — výber N otázok
|
### Na skúške — výber N otázok
|
||||||
@@ -236,8 +212,8 @@ struct Kviz {
|
|||||||
|
|
||||||
impl Kviz {
|
impl Kviz {
|
||||||
fn nahodnych_n(&self, n: usize) -> Vec<&Otazka> {
|
fn nahodnych_n(&self, n: usize) -> Vec<&Otazka> {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::rng();
|
||||||
self.otazky.choose_multiple(&mut rng, n).collect()
|
self.otazky.sample(&mut rng, n).collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -246,89 +222,77 @@ impl Kviz {
|
|||||||
|
|
||||||
**4a.** Máš 20 študentov. Vyber 5 náhodných na skúšanie.
|
**4a.** Máš 20 študentov. Vyber 5 náhodných na skúšanie.
|
||||||
|
|
||||||
**4b.** Máš balíček kariet (Vec<String>). Rozdaj 7 kariet — vyber 7 náhodných.
|
**4b.** Máš balíček kariet (Vec<String>). Rozdaj 7 kariet.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Kapitola 5: shuffle — zamiešanie
|
## Kapitola 5: shuffle — zamiešanie
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::SliceRandom; // shuffle je v SliceRandom!
|
||||||
|
|
||||||
let mut cisla = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
let mut cisla = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::rng();
|
||||||
|
|
||||||
// shuffle — zamieša NA MIESTE (mení Vec)
|
// shuffle — zamieša NA MIESTE (mení Vec)
|
||||||
cisla.shuffle(&mut rng);
|
cisla.shuffle(&mut rng);
|
||||||
// cisla je teraz napr. [7, 2, 9, 1, 5, 3, 10, 4, 8, 6]
|
// napr. [7, 2, 9, 1, 5, 3, 10, 4, 8, 6]
|
||||||
```
|
```
|
||||||
|
|
||||||
**`&mut self`** — shuffle mení vektor, preto `let mut cisla` a `&mut rng`.
|
**Import:** `use rand::seq::SliceRandom;` — shuffle je v SliceRandom, nie IndexedRandom!
|
||||||
|
|
||||||
### Kedy shuffle vs choose_multiple
|
### Kedy čo
|
||||||
|
|
||||||
| Chcem... | Použi |
|
| Chcem... | Použi | Import |
|
||||||
|----------|-------|
|
|----------|-------|--------|
|
||||||
| 1 náhodný prvok | `choose` |
|
| 1 náhodný prvok | `.choose()` | `IndexedRandom` |
|
||||||
| N náhodných (bez zmeny originálu) | `choose_multiple` |
|
| N náhodných (bez zmeny originálu) | `.sample()` | `IndexedRandom` |
|
||||||
| Zamiešať celý zoznam | `shuffle` |
|
| Zamiešať celý zoznam | `.shuffle()` | `SliceRandom` |
|
||||||
| Prvých N po zamiešaní | `shuffle` + `.iter().take(n)` |
|
|
||||||
|
|
||||||
### Na skúške — zamiešanie otázok/odpovedí
|
### Na skúške — zamiešanie otázok
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
use rand::seq::SliceRandom;
|
||||||
|
|
||||||
impl Kviz {
|
impl Kviz {
|
||||||
fn hraj(&mut self) {
|
fn hraj(&mut self) {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::rng();
|
||||||
|
|
||||||
// Zamieša poradie otázok
|
|
||||||
self.otazky.shuffle(&mut rng);
|
self.otazky.shuffle(&mut rng);
|
||||||
|
|
||||||
for otazka in &self.otazky {
|
for otazka in &self.otazky {
|
||||||
println!("{}", otazka.text);
|
println!("{}", otazka.text);
|
||||||
// ...
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Alebo zamiešaj odpovede ku každej otázke
|
|
||||||
impl Otazka {
|
|
||||||
fn zamiesaj_odpovede(&mut self) {
|
|
||||||
let mut rng = rand::thread_rng();
|
|
||||||
self.odpovede.shuffle(&mut rng);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Úlohy 5
|
### Úlohy 5
|
||||||
|
|
||||||
**5a.** Máš vektor kariet. Zamieša ho. Vypíš prvých 5 (to je "ruka" hráča).
|
**5a.** Máš vektor kariet. Zamiešaj. Vypíš prvých 5.
|
||||||
|
|
||||||
**5b.** Máš Vec<Otazka>. Zamieša poradie. Vypíš otázky v novom poradí.
|
**5b.** Čo je zle?
|
||||||
|
|
||||||
**5c.** Čo je zle?
|
|
||||||
```rust
|
```rust
|
||||||
let cisla = vec![1, 2, 3, 4, 5];
|
let cisla = vec![1, 2, 3, 4, 5];
|
||||||
cisla.shuffle(&mut rand::thread_rng());
|
cisla.shuffle(&mut rand::rng());
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Kapitola 6: Generovanie náhodných znakov a reťazcov
|
## Kapitola 6: Náhodné znaky a reťazce
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use rand::distributions::Alphanumeric;
|
use rand::distr::Alphanumeric; // distr, nie distributions!
|
||||||
|
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::rng();
|
||||||
|
|
||||||
// Náhodný ASCII znak a-z
|
// Náhodný ASCII znak a-z
|
||||||
let znak: char = rng.gen_range(b'a'..=b'z') as char;
|
let znak: char = rng.random_range(b'a'..=b'z') as char;
|
||||||
|
|
||||||
// Náhodný veľký znak A-Z
|
// Náhodný veľký znak A-Z
|
||||||
let znak: char = rng.gen_range(b'A'..=b'Z') as char;
|
let znak: char = rng.random_range(b'A'..=b'Z') as char;
|
||||||
|
|
||||||
// Náhodný alfanumerický reťazec (a-z, A-Z, 0-9)
|
// Alfanumerický reťazec (a-z, A-Z, 0-9)
|
||||||
let heslo: String = (0..12)
|
let heslo: String = (0..12)
|
||||||
.map(|_| rng.sample(Alphanumeric) as char)
|
.map(|_| rng.sample(Alphanumeric) as char)
|
||||||
.collect();
|
.collect();
|
||||||
@@ -338,10 +302,10 @@ let heslo: String = (0..12)
|
|||||||
### Výber náhodného znaku z reťazca
|
### Výber náhodného znaku z reťazca
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::IndexedRandom;
|
||||||
|
|
||||||
let abeceda: Vec<char> = "abcdefghijklmnopqrstuvwxyz".chars().collect();
|
let abeceda: Vec<char> = "abcdefghijklmnopqrstuvwxyz".chars().collect();
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::rng();
|
||||||
|
|
||||||
let nahodny_znak = abeceda.choose(&mut rng);
|
let nahodny_znak = abeceda.choose(&mut rng);
|
||||||
// Some(&'m')
|
// Some(&'m')
|
||||||
@@ -349,60 +313,34 @@ let nahodny_znak = abeceda.choose(&mut rng);
|
|||||||
|
|
||||||
### Úlohy 6
|
### Úlohy 6
|
||||||
|
|
||||||
**6a.** Vygeneruj náhodné heslo dlhé 10 znakov, len z malých písmen a-z.
|
**6a.** Vygeneruj heslo: 10 znakov, len malé písmená a-z.
|
||||||
|
|
||||||
**6b.** Vygeneruj náhodné meno: veľké prvé písmeno + 4 malé písmená.
|
**6b.** Vygeneruj náhodné meno: veľké prvé + 4 malé písmená.
|
||||||
|
|
||||||
**6c.** Máš abecedu slovenských znakov (vrátane diakritiky) ako Vec<char>. Vyber 5 náhodných.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Kapitola 7: gen_bool a bernoulli — pravdepodobnosť
|
## Kapitola 7: random_bool — pravdepodobnosť
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::rng();
|
||||||
|
|
||||||
// 50% šanca na true
|
// 50% šanca na true
|
||||||
let minca: bool = rng.gen_bool(0.5);
|
let minca: bool = rng.random_bool(0.5);
|
||||||
|
|
||||||
// 70% šanca na true
|
// 70% šanca na true
|
||||||
let dost_casto: bool = rng.gen_bool(0.7);
|
let dost_casto: bool = rng.random_bool(0.7);
|
||||||
|
|
||||||
// 10% šanca na true
|
// 10% šanca na true
|
||||||
let zriedka: bool = rng.gen_bool(0.1);
|
let zriedka: bool = rng.random_bool(0.1);
|
||||||
|
|
||||||
// 100% true
|
|
||||||
let vzdy: bool = rng.gen_bool(1.0);
|
|
||||||
|
|
||||||
// 0% true
|
|
||||||
let nikdy: bool = rng.gen_bool(0.0);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Praktické použitie
|
|
||||||
|
|
||||||
```rust
|
|
||||||
// Šanca na kritický zásah v hre
|
|
||||||
fn je_kriticky_zasah(sila: f64) -> bool {
|
|
||||||
let mut rng = rand::thread_rng();
|
|
||||||
rng.gen_bool(sila / 100.0) // sila 25 → 25% šanca
|
|
||||||
}
|
|
||||||
|
|
||||||
// Náhodná udalosť
|
|
||||||
fn nahodna_udalost() {
|
|
||||||
let mut rng = rand::thread_rng();
|
|
||||||
if rng.gen_bool(0.3) {
|
|
||||||
println!("Nastala špeciálna udalosť! (30% šanca)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Úlohy 7
|
### Úlohy 7
|
||||||
|
|
||||||
**7a.** Simuluj 1000 hodov mincou. Koľkokrát padol orol (true)?
|
**7a.** Simuluj 1000 hodov mincou. Koľkokrát padol orol (true)?
|
||||||
|
|
||||||
**7b.** Napíš funkciu, ktorá vráti "Výhra!" s pravdepodobnosťou 15% a "Skús znova" inak.
|
**7b.** Funkcia vráti "Výhra!" s 15% pravdepodobnosťou, inak "Skús znova".
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -423,8 +361,8 @@ fn prompt(text: &str) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::rng();
|
||||||
let tajne: i32 = rng.gen_range(1..=100);
|
let tajne: i32 = rng.random_range(1..=100);
|
||||||
let mut pokusy = 0;
|
let mut pokusy = 0;
|
||||||
|
|
||||||
println!("Hádaj číslo od 1 do 100!");
|
println!("Hádaj číslo od 1 do 100!");
|
||||||
@@ -456,7 +394,7 @@ fn main() {
|
|||||||
### Obesenec s náhodným slovom
|
### Obesenec s náhodným slovom
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::IndexedRandom;
|
||||||
use std::collections::{HashSet, HashMap};
|
use std::collections::{HashSet, HashMap};
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
|
||||||
@@ -469,14 +407,13 @@ fn nacitaj_znak() -> Option<char> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Slovník
|
|
||||||
let slovnik: HashMap<&str, Vec<&str>> = HashMap::from([
|
let slovnik: HashMap<&str, Vec<&str>> = HashMap::from([
|
||||||
("zvierata", vec!["pes", "macka", "kon", "krava", "zajac"]),
|
("zvierata", vec!["pes", "macka", "kon", "krava", "zajac"]),
|
||||||
("jedlo", vec!["pizza", "burger", "salat", "rizoto"]),
|
("jedlo", vec!["pizza", "burger", "salat", "rizoto"]),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Vyber náhodnú kategóriu a slovo
|
// Vyber náhodnú kategóriu a slovo
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::rng();
|
||||||
let kategorie: Vec<&&str> = slovnik.keys().collect();
|
let kategorie: Vec<&&str> = slovnik.keys().collect();
|
||||||
let kategoria = **kategorie.choose(&mut rng).unwrap();
|
let kategoria = **kategorie.choose(&mut rng).unwrap();
|
||||||
let slova = &slovnik[kategoria];
|
let slova = &slovnik[kategoria];
|
||||||
@@ -484,37 +421,32 @@ fn main() {
|
|||||||
|
|
||||||
println!("Kategória: {}", kategoria);
|
println!("Kategória: {}", kategoria);
|
||||||
|
|
||||||
// Stav hry
|
|
||||||
let mut uhadnute: HashSet<char> = HashSet::new();
|
let mut uhadnute: HashSet<char> = HashSet::new();
|
||||||
let mut skusane: HashSet<char> = HashSet::new();
|
let mut skusane: HashSet<char> = HashSet::new();
|
||||||
let mut zivoty: u8 = 6;
|
let mut zivoty: u8 = 6;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
// Zobraz slovo
|
|
||||||
let zobrazene: String = slovo.chars().map(|c| {
|
let zobrazene: String = slovo.chars().map(|c| {
|
||||||
if uhadnute.contains(&c) { c } else { '_' }
|
if uhadnute.contains(&c) { c } else { '_' }
|
||||||
}).collect();
|
}).collect();
|
||||||
println!("\n{} (životov: {})", zobrazene, zivoty);
|
println!("\n{} (životov: {})", zobrazene, zivoty);
|
||||||
|
|
||||||
// Výhra?
|
|
||||||
if slovo.chars().all(|c| uhadnute.contains(&c)) {
|
if slovo.chars().all(|c| uhadnute.contains(&c)) {
|
||||||
println!("Vyhral si! Slovo bolo: {}", slovo);
|
println!("Vyhral si! Slovo bolo: {}", slovo);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Prehra?
|
|
||||||
if zivoty == 0 {
|
if zivoty == 0 {
|
||||||
println!("Prehral si! Slovo bolo: {}", slovo);
|
println!("Prehral si! Slovo bolo: {}", slovo);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vstup
|
|
||||||
let Some(pismeno) = nacitaj_znak() else {
|
let Some(pismeno) = nacitaj_znak() else {
|
||||||
println!("Neplatný vstup");
|
println!("Neplatný vstup");
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
if !skusane.insert(pismeno) {
|
if !skusane.insert(pismeno) {
|
||||||
println!("Toto písmeno si už skúšal!");
|
println!("Už si skúšal!");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -531,29 +463,25 @@ fn main() {
|
|||||||
|
|
||||||
### Úlohy 8
|
### Úlohy 8
|
||||||
|
|
||||||
**8a.** Napíš hru "hádaj číslo" kde rozsah závisí od obtiažnosti:
|
**8a.** Napíš "hádaj číslo" s obtiažnosťou: ľahká (1–10), stredná (1–50), ťažká (1–100).
|
||||||
- Ľahká: 1–10
|
|
||||||
- Stredná: 1–50
|
|
||||||
- Ťažká: 1–100
|
|
||||||
Použi prompt na výber obtiažnosti.
|
|
||||||
|
|
||||||
**8b.** Napíš jednoduchú kvízovú hru: 5 otázok z náhodne zamiešaného poolu. Každá otázka má 4 odpovede (zamiešané). Hráč zadáva číslo odpovede.
|
**8b.** Napíš kvízovú hru: 5 otázok z náhodne zamiešaného poolu, hráč zadáva číslo odpovede.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Kapitola 9: Náhodné s kolekciami
|
## Kapitola 9: Náhodné z HashMap a HashSet
|
||||||
|
|
||||||
### Náhodný kľúč z HashMap
|
Pre iterátory (nie slice) treba `IteratorRandom`:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use rand::seq::IteratorRandom; // TOTO pre .choose na iterátore!
|
use rand::seq::IteratorRandom; // pre .choose() na iterátore
|
||||||
|
|
||||||
let mut mapa = HashMap::new();
|
let mut mapa = HashMap::new();
|
||||||
mapa.insert("a", 1);
|
mapa.insert("a", 1);
|
||||||
mapa.insert("b", 2);
|
mapa.insert("b", 2);
|
||||||
mapa.insert("c", 3);
|
mapa.insert("c", 3);
|
||||||
|
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::rng();
|
||||||
|
|
||||||
// Náhodný kľúč
|
// Náhodný kľúč
|
||||||
let kluc = mapa.keys().choose(&mut rng);
|
let kluc = mapa.keys().choose(&mut rng);
|
||||||
@@ -564,33 +492,30 @@ let par = mapa.iter().choose(&mut rng);
|
|||||||
// Some((&"a", &1))
|
// Some((&"a", &1))
|
||||||
```
|
```
|
||||||
|
|
||||||
**Import:** `use rand::seq::IteratorRandom;` — toto umožní `.choose()` na akomkoľvek iterátore, nielen na slice.
|
|
||||||
|
|
||||||
### Náhodný prvok z HashSet
|
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
// HashSet — rovnako
|
||||||
use rand::seq::IteratorRandom;
|
use rand::seq::IteratorRandom;
|
||||||
|
|
||||||
let mnozina: HashSet<String> = vec!["pes", "mačka", "kôň"]
|
let mnozina: HashSet<String> = vec!["pes", "mačka", "kôň"]
|
||||||
.into_iter().map(String::from).collect();
|
.into_iter().map(String::from).collect();
|
||||||
|
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::rng();
|
||||||
let nahodny = mnozina.iter().choose(&mut rng);
|
let nahodny = mnozina.iter().choose(&mut rng);
|
||||||
// Some(&"mačka")
|
// Some(&"mačka")
|
||||||
```
|
```
|
||||||
|
|
||||||
### Úlohy 9
|
### Úlohy 9
|
||||||
|
|
||||||
**9a.** Máš HashMap kategórií. Vyber náhodnú kategóriu (kľúč), potom náhodné slovo z nej.
|
**9a.** Máš HashMap kategórií. Vyber náhodnú kategóriu, potom náhodné slovo z nej.
|
||||||
|
|
||||||
**9b.** Máš HashSet<char> skúšaných písmen. Vyber náhodné písmeno z abecedy, ktoré ešte NIE JE v sete.
|
**9b.** Máš HashSet<char> skúšaných písmen. Vyber písmeno z abecedy, ktoré ešte NIE JE v sete.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Kapitola 10: Kompletný vzor — SpravcaHry zo skúšky
|
## Kapitola 10: Kompletný vzor — SpravcaHry zo skúšky
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::IndexedRandom;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@@ -613,21 +538,13 @@ impl SpravcaHry {
|
|||||||
std::fs::write(cesta, json).is_ok()
|
std::fs::write(cesta, json).is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NAJDÔLEŽITEJŠIA METÓDA — náhodné slovo z kategórie
|
|
||||||
pub fn vytvor_novu_hru(&self, kategoria: &str) -> Option<Hra> {
|
pub fn vytvor_novu_hru(&self, kategoria: &str) -> Option<Hra> {
|
||||||
// 1. Nájdi kategóriu
|
|
||||||
let slova = self.slovnik.get(kategoria)?;
|
let slova = self.slovnik.get(kategoria)?;
|
||||||
|
|
||||||
// 2. Prázdna kategória → None
|
|
||||||
if slova.is_empty() {
|
if slova.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
let mut rng = rand::rng();
|
||||||
// 3. Náhodný výber
|
|
||||||
let mut rng = rand::thread_rng();
|
|
||||||
let slovo = slova.choose(&mut rng)?;
|
let slovo = slova.choose(&mut rng)?;
|
||||||
|
|
||||||
// 4. Vytvor hru
|
|
||||||
Some(Hra::new(slovo))
|
Some(Hra::new(slovo))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -718,18 +635,11 @@ fn main() {
|
|||||||
|
|
||||||
### Úlohy 10
|
### Úlohy 10
|
||||||
|
|
||||||
**10a.** Napíš celý SpravcaHry od nuly bez pozerania. Musíš mať:
|
**10a.** Napíš celý SpravcaHry od nuly bez pozerania.
|
||||||
- `slovnik: HashMap<String, Vec<String>>`
|
|
||||||
- `nacitaj_zo_suboru`, `uloz_do_suboru`
|
|
||||||
- `pridaj_kategoriu`, `pridaj_slovo`
|
|
||||||
- `vytvor_novu_hru` s `choose`
|
|
||||||
|
|
||||||
**10b.** Napíš main.rs s clapom bez pozerania. Subcommands:
|
**10b.** Napíš main.rs s clapom bez pozerania.
|
||||||
- `pridaj-kategoriu <cesta> <kategoria>`
|
|
||||||
- `pridaj-slovo <cesta> <kategoria> <slovo>`
|
|
||||||
- `hraj <cesta> <kategoria>`
|
|
||||||
|
|
||||||
**10c.** Rozšír SpravcaHry o metódu `nahodna_kategoria(&self) -> Option<&String>` — vyber náhodnú kategóriu. Použi `IteratorRandom`.
|
**10c.** Rozšír o metódu `nahodna_kategoria(&self) -> Option<&String>`. Použi `IteratorRandom`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -737,13 +647,28 @@ fn main() {
|
|||||||
|
|
||||||
| Chcem... | Import | Metóda |
|
| Chcem... | Import | Metóda |
|
||||||
|----------|--------|--------|
|
|----------|--------|--------|
|
||||||
| Náhodné číslo | `use rand::Rng;` | `rng.gen()`, `rng.gen_range(1..=6)` |
|
| Náhodné číslo | `use rand::Rng;` | `rng.random()` |
|
||||||
| Náhodný bool | `use rand::Rng;` | `rng.gen_bool(0.5)` |
|
| Číslo v rozsahu | `use rand::Rng;` | `rng.random_range(1..=6)` |
|
||||||
| Náhodný prvok z Vec/slice | `use rand::seq::SliceRandom;` | `vec.choose(&mut rng)` |
|
| Náhodný bool | `use rand::Rng;` | `rng.random_bool(0.5)` |
|
||||||
| Viac náhodných prvkov | `use rand::seq::SliceRandom;` | `vec.choose_multiple(&mut rng, n)` |
|
| Náhodný prvok z Vec | `use rand::seq::IndexedRandom;` | `vec.choose(&mut rng)` |
|
||||||
|
| N náhodných prvkov | `use rand::seq::IndexedRandom;` | `vec.sample(&mut rng, n)` |
|
||||||
| Zamiešať Vec | `use rand::seq::SliceRandom;` | `vec.shuffle(&mut rng)` |
|
| Zamiešať Vec | `use rand::seq::SliceRandom;` | `vec.shuffle(&mut rng)` |
|
||||||
| Náhodný z iterátora (HashMap, HashSet) | `use rand::seq::IteratorRandom;` | `iter.choose(&mut rng)` |
|
| Náhodný z iterátora | `use rand::seq::IteratorRandom;` | `iter.choose(&mut rng)` |
|
||||||
| Alfanumerické znaky | `use rand::distributions::Alphanumeric;` | `rng.sample(Alphanumeric)` |
|
| Alfanumerické znaky | `use rand::distr::Alphanumeric;` | `rng.sample(Alphanumeric) as char` |
|
||||||
|
| Všetko naraz | `use rand::prelude::*;` | zahŕňa Rng, IndexedRandom, SliceRandom |
|
||||||
|
|
||||||
**Vždy:** `let mut rng = rand::thread_rng();` — vytvor generátor.
|
**Vždy:** `let mut rng = rand::rng();`
|
||||||
**Vždy:** `&mut rng` — predávaj ako meniteľnú referenciu.
|
|
||||||
|
## Zmeny oproti starým verziám (0.8)
|
||||||
|
|
||||||
|
Ak niekde vidíš starý kód, tu je preklad:
|
||||||
|
|
||||||
|
| Staré (rand 0.8) | Nové (rand 0.9+) |
|
||||||
|
|-------------------|-------------------|
|
||||||
|
| `rand::thread_rng()` | `rand::rng()` |
|
||||||
|
| `rng.gen()` | `rng.random()` |
|
||||||
|
| `rng.gen_range(1..=6)` | `rng.random_range(1..=6)` |
|
||||||
|
| `rng.gen_bool(0.5)` | `rng.random_bool(0.5)` |
|
||||||
|
| `use rand::distributions::` | `use rand::distr::` |
|
||||||
|
| `vec.choose_multiple(&mut rng, n)` | `vec.sample(&mut rng, n)` |
|
||||||
|
| `use rand::seq::SliceRandom;` (pre choose) | `use rand::seq::IndexedRandom;` |
|
||||||
|
|||||||
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