clap2
This commit is contained in:
268
priprava/rust_priprava11.md
Normal file
268
priprava/rust_priprava11.md
Normal file
@@ -0,0 +1,268 @@
|
|||||||
|
# clap → match → volanie metód — kde robíš chybu
|
||||||
|
|
||||||
|
Tvoj problém nie je clap. Clap máš dobre. Tvoj problém je toto:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
Sc::DajKnihuIsbn { cesta, isbn } => {
|
||||||
|
Kniznica::daj_knihu_podla_isbn(isbn); // ZLE
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Tri chyby na jednom riadku:
|
||||||
|
1. Nikde si nenačítal knižnicu zo súboru
|
||||||
|
2. Voláš metódu ako statickú (`Kniznica::`) namiesto na inštancii (`kniznica.`)
|
||||||
|
3. Ignoruješ návratovú hodnotu
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Pravidlo 1: Najprv načítaj, potom volaj
|
||||||
|
|
||||||
|
Metódy ako `daj_knihu_podla_isbn` sú `&self` metódy — potrebujú inštanciu. Tú musíš najprv vytvoriť z JSON súboru.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// ZLE — Kniznica neexistuje, voláš na type
|
||||||
|
Kniznica::daj_knihu_podla_isbn(isbn);
|
||||||
|
|
||||||
|
// DOBRE — najprv načítaj, potom volaj na inštancii
|
||||||
|
let kniznica = Kniznica::nacitaj_zo_suboru(&cesta).unwrap_or_default();
|
||||||
|
kniznica.daj_knihu_podla_isbn(&isbn);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Pravidlo 2: Statické vs inštančné metódy
|
||||||
|
|
||||||
|
Pozri sa na signatúru metódy. To ti povie ako ju volať.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// STATICKÁ metóda — nemá self, volaj cez Typ::
|
||||||
|
fn nacitaj_zo_suboru(cesta: &PathBuf) -> Option<Kniznica>
|
||||||
|
// Volanie:
|
||||||
|
let kniznica = Kniznica::nacitaj_zo_suboru(&cesta);
|
||||||
|
|
||||||
|
// &self metóda — len čítanie, volaj cez instancia.
|
||||||
|
fn daj_knihu_podla_isbn(&self, isbn: &str) -> Option<&Kniha>
|
||||||
|
// Volanie:
|
||||||
|
let vysledok = kniznica.daj_knihu_podla_isbn(&isbn);
|
||||||
|
|
||||||
|
// &mut self metóda — mení dáta, volaj cez mut instancia.
|
||||||
|
fn pridaj_knihu(&mut self, kniha: Kniha) -> Result<(), ()>
|
||||||
|
// Volanie:
|
||||||
|
let mut kniznica = Kniznica::nacitaj_zo_suboru(&cesta).unwrap_or_default();
|
||||||
|
let vysledok = kniznica.pridaj_knihu(kniha);
|
||||||
|
```
|
||||||
|
|
||||||
|
Zhrnutie:
|
||||||
|
|
||||||
|
| Signatúra | Čo potrebuješ | Volanie |
|
||||||
|
|-----------|---------------|---------|
|
||||||
|
| `fn nieco(cesta: &PathBuf)` — bez self | nič | `Kniznica::nieco(&cesta)` |
|
||||||
|
| `fn nieco(&self, ...)` | `let kniznica = ...` | `kniznica.nieco(...)` |
|
||||||
|
| `fn nieco(&mut self, ...)` | `let mut kniznica = ...` | `kniznica.nieco(...)` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Pravidlo 3: Spracuj návratovú hodnotu
|
||||||
|
|
||||||
|
Každá metóda niečo vracia. Musíš s tým niečo urobiť.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// Option<&Kniha> — buď existuje, alebo nie
|
||||||
|
match kniznica.daj_knihu_podla_isbn(&isbn) {
|
||||||
|
Some(kniha) => println!("{}", kniha),
|
||||||
|
None => println!("Kniha nenájdená"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vec<&Kniha> — môže byť prázdny
|
||||||
|
let knihy = kniznica.daj_knihy_autora(&autor);
|
||||||
|
if knihy.is_empty() {
|
||||||
|
println!("Žiadne knihy");
|
||||||
|
} else {
|
||||||
|
for kniha in &knihy {
|
||||||
|
println!("{}", kniha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Result<Kniha, ()> — podarilo sa alebo nie
|
||||||
|
match kniznica.odstran_knihu(&isbn) {
|
||||||
|
Ok(kniha) => println!("Odstránená: {}", kniha),
|
||||||
|
Err(()) => println!("Kniha nenájdená"),
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Pravidlo 4: Ak meníš dáta, ulož na konci
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// Čítacie metódy (&self) — NEUKLADAJ
|
||||||
|
Sc::DajKnihuIsbn { cesta, isbn } => {
|
||||||
|
let kniznica = Kniznica::nacitaj_zo_suboru(&cesta).unwrap_or_default();
|
||||||
|
// daj_knihu_podla_isbn je &self — len číta
|
||||||
|
match kniznica.daj_knihu_podla_isbn(&isbn) {
|
||||||
|
Some(kniha) => println!("{}", kniha),
|
||||||
|
None => println!("Nenájdená"),
|
||||||
|
}
|
||||||
|
// ŽIADNE uloženie — nič sa nezmenilo
|
||||||
|
}
|
||||||
|
|
||||||
|
// Meniace metódy (&mut self) — ULOŽ!
|
||||||
|
Sc::OdstranKnihu { cesta, isbn } => {
|
||||||
|
let mut kniznica = Kniznica::nacitaj_zo_suboru(&cesta).unwrap_or_default();
|
||||||
|
// odstran_knihu je &mut self — mení dáta
|
||||||
|
match kniznica.odstran_knihu(&isbn) {
|
||||||
|
Ok(kniha) => {
|
||||||
|
println!("Odstránená: {}", kniha);
|
||||||
|
kniznica.uloz_do_suboru(&cesta); // ULOŽ ZMENY!
|
||||||
|
}
|
||||||
|
Err(()) => println!("Nenájdená"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Keď uložiť:
|
||||||
|
- `pridaj_knihu` — áno (pridávaš)
|
||||||
|
- `odstran_knihu` — áno (mažeš)
|
||||||
|
- `daj_knihu_podla_isbn` — nie (len čítaš)
|
||||||
|
- `daj_knihy_autora` — nie
|
||||||
|
- `vypis_vydavatelstva_a_pocet_knih` — nie
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Pravidlo 5: &isbn vs isbn — referencie v argumentoch
|
||||||
|
|
||||||
|
Pozri sa čo metóda chce. Ak chce `&str`, daj referenciu na String.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// Metóda chce: isbn: &str
|
||||||
|
fn daj_knihu_podla_isbn(&self, isbn: &str) -> Option<&Kniha>
|
||||||
|
|
||||||
|
// Ty máš: isbn: String (z clapu)
|
||||||
|
// Volanie:
|
||||||
|
kniznica.daj_knihu_podla_isbn(&isbn) // & premení String na &str
|
||||||
|
```
|
||||||
|
|
||||||
|
Vždy keď metóda berie `&str` a ty máš `String`, daj `&`:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
kniznica.daj_knihu_podla_isbn(&isbn); // String → &str
|
||||||
|
kniznica.daj_knihy_autora(&autor); // String → &str
|
||||||
|
kniznica.odstran_knihu(&isbn); // String → &str
|
||||||
|
kniznica.daj_knihy_podla_stavu(stav); // Stav sa predáva priamo (nie referencia)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tvoj kód opravený
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use clap::{Parser, Subcommand};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use riesenie1::Kniznica;
|
||||||
|
|
||||||
|
#[derive(Parser, Debug)]
|
||||||
|
struct Args {
|
||||||
|
#[command(subcommand)]
|
||||||
|
cmd: Sc,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Subcommand, Debug)]
|
||||||
|
pub enum Sc {
|
||||||
|
DajKnihuIsbn {
|
||||||
|
cesta: PathBuf,
|
||||||
|
isbn: String,
|
||||||
|
},
|
||||||
|
DajKnihyAutora {
|
||||||
|
cesta: PathBuf,
|
||||||
|
autor: String,
|
||||||
|
},
|
||||||
|
OdstranKnihu {
|
||||||
|
cesta: PathBuf,
|
||||||
|
isbn: String,
|
||||||
|
},
|
||||||
|
VypisVydavatelstva {
|
||||||
|
cesta: PathBuf,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let args = Args::parse();
|
||||||
|
|
||||||
|
match args.cmd {
|
||||||
|
Sc::DajKnihuIsbn { cesta, isbn } => {
|
||||||
|
// 1. Načítaj
|
||||||
|
let kniznica = Kniznica::nacitaj_zo_suboru(&cesta).unwrap_or_default();
|
||||||
|
// 2. Zavolaj na inštancii
|
||||||
|
// 3. Spracuj výsledok
|
||||||
|
match kniznica.daj_knihu_podla_isbn(&isbn) {
|
||||||
|
Some(kniha) => println!("{}", kniha),
|
||||||
|
None => println!("Kniha s ISBN {} nenájdená", isbn),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sc::DajKnihyAutora { cesta, autor } => {
|
||||||
|
let kniznica = Kniznica::nacitaj_zo_suboru(&cesta).unwrap_or_default();
|
||||||
|
let knihy = kniznica.daj_knihy_autora(&autor);
|
||||||
|
if knihy.is_empty() {
|
||||||
|
println!("Žiadne knihy od autora {}", autor);
|
||||||
|
} else {
|
||||||
|
for kniha in &knihy {
|
||||||
|
println!("{}", kniha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sc::OdstranKnihu { cesta, isbn } => {
|
||||||
|
// mut! lebo odstran_knihu je &mut self
|
||||||
|
let mut kniznica = Kniznica::nacitaj_zo_suboru(&cesta).unwrap_or_default();
|
||||||
|
match kniznica.odstran_knihu(&isbn) {
|
||||||
|
Ok(kniha) => {
|
||||||
|
println!("Odstránená: {}", kniha);
|
||||||
|
kniznica.uloz_do_suboru(&cesta); // ULOŽ!
|
||||||
|
}
|
||||||
|
Err(()) => println!("Kniha s ISBN {} nenájdená", isbn),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sc::VypisVydavatelstva { cesta } => {
|
||||||
|
let kniznica = Kniznica::nacitaj_zo_suboru(&cesta).unwrap_or_default();
|
||||||
|
// Táto metóda sama vypíše — len ju zavolaj
|
||||||
|
kniznica.vypis_vydavatelstva_a_pocet_knih();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Cvičenie: Doplň match arms
|
||||||
|
|
||||||
|
Dopíš chýbajúce časti. Signatúry metód sú v komentároch.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// SIGNATÚRY:
|
||||||
|
// fn nacitaj_zo_suboru(cesta: &PathBuf) -> Option<Kontakty>
|
||||||
|
// fn uloz_do_suboru(&self, cesta: &PathBuf) -> bool
|
||||||
|
// fn pridaj(&mut self, kontakt: Kontakt) -> Result<(), ()>
|
||||||
|
// fn odstran(&mut self, meno: &str) -> Result<Kontakt, ()>
|
||||||
|
// fn hladaj(&self, meno: &str) -> Option<&Kontakt>
|
||||||
|
// fn vsetky(&self) -> Vec<&Kontakt>
|
||||||
|
|
||||||
|
match args.cmd {
|
||||||
|
Sc::Pridaj { cesta, meno, telefon } => {
|
||||||
|
// TODO: načítaj (mut!), vytvor Kontakt, pridaj, ulož ak ok
|
||||||
|
}
|
||||||
|
Sc::Odstran { cesta, meno } => {
|
||||||
|
// TODO: načítaj (mut!), odstráň, vypíš výsledok, ulož ak ok
|
||||||
|
}
|
||||||
|
Sc::Hladaj { cesta, meno } => {
|
||||||
|
// TODO: načítaj, hľadaj, vypíš Some/None
|
||||||
|
}
|
||||||
|
Sc::Vypis { cesta } => {
|
||||||
|
// TODO: načítaj, zavolaj vsetky(), iteruj a vypíš
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Skús to vyplniť sám. Ak nevieš, pozri na opravený kód vyššie — vzor je vždy rovnaký:
|
||||||
|
1. `let (mut) x = Typ::nacitaj_zo_suboru(&cesta).unwrap_or_default();`
|
||||||
|
2. `let vysledok = x.metoda(&arg);`
|
||||||
|
3. `match/if/for` na výsledku
|
||||||
|
4. Ak `&mut self` metóda → `x.uloz_do_suboru(&cesta);`
|
||||||
Reference in New Issue
Block a user