Files
JR-priprava-na-skusku/priprava/rust_priprava8.md
Priec 5182e2f833 str
2026-02-28 23:21:09 +01:00

23 KiB
Raw Permalink Blame History

String, &str, char — krok za krokom

Každá kapitola: prečítaj, pozri príklady, urob úlohy. Až potom choď ďalej.


Kapitola 1: Čo je čo

V Ruste existujú 3 typy pre prácu s textom:

Typ Čo to je Vlastní dáta? Veľkosť
String Vlastnený, meniteľný reťazec na heape Áno Rastie/zmenšuje sa
&str Referencia na kúsok textu (string slice) Nie (len pozerá) Fixná
char Jeden Unicode znak Áno 4 bajty vždy
// String — vlastní dáta, môžeš meniť
let mut s: String = String::from("ahoj");
s.push_str(" svet");  // OK — je mut a vlastní dáta

// &str — len referencia, nemôžeš meniť obsah
let slice: &str = "ahoj svet";
// slice.push_str("!"); // CHYBA — &str je len pohľad

// char — jeden znak
let c: char = 'a';
let emoji: char = '🦀';  // aj emoji je jeden char

Analógia:

  • String je ako vlastný zošit — píšeš doň, pridávaš strany
  • &str je ako pohľad cez okno na cudzí zošit — vidíš text, ale nemôžeš ho meniť
  • char je ako jedno písmeno

Úlohy 1

1a. Ktorý typ použiješ v štruktúre? Prečo?

struct Kniha {
    nazov: ???,  // String alebo &str?
}

1b. Čo je zle? Oprav:

let s: &str = "ahoj";
s.push_str(" svet");

1c. Aký je typ každej premennej?

let a = "ahoj";
let b = String::from("ahoj");
let c = 'a';
let d = &b[..];
let e = b.as_str();

Kapitola 2: Vytváranie String

Existuje veľa spôsobov ako vytvoriť String:

// 1. String::from
let s = String::from("ahoj");

// 2. .to_string() — funguje na čomkoľvek s Display
let s = "ahoj".to_string();
let s = 42.to_string();        // "42"
let s = 3.14.to_string();      // "3.14"
let s = true.to_string();      // "true"

// 3. String::new() — prázdny
let s = String::new();  // ""

// 4. format! — ako println!, ale vráti String
let meno = "Anna";
let vek = 25;
let s = format!("{}{} rokov", meno, vek);
// "Anna má 25 rokov"

// 5. .to_owned() — z &str na String
let slice: &str = "ahoj";
let owned: String = slice.to_owned();

// 6. .into() — Rust odvodí konverziu
let s: String = "ahoj".into();

Ktorý použiť:

  • String::from("...") alebo "...".to_string() — oboje je rovnaké, použi čo sa ti páči
  • format!() — keď skladáš z viacerých častí
  • String::new() — keď budeš pridávať postupne

Úlohy 2

2a. Vytvor String z čísla 42, z boolu false, z float 3.14. Vypíš ich.

2b. Máš premenné meno: &str a vek: u32. Vytvor String vo formáte "Meno: Anna, Vek: 25" pomocou format!.

2c. Vytvor prázdny String a postupne do neho pridaj 3 slová (použi push_str). Výsledok vypíš.


Kapitola 3: Konverzie medzi String a &str

// &str → String (3 spôsoby, všetky robia to isté)
let slice: &str = "ahoj";
let owned1: String = slice.to_string();
let owned2: String = slice.to_owned();
let owned3: String = String::from(slice);

// String → &str (2 spôsoby)
let owned: String = String::from("ahoj");
let slice1: &str = &owned;         // automatická dereferencia
let slice2: &str = owned.as_str(); // explicitné

// String → &str v parametroch funkcie — automaticky!
fn prijmi_str(s: &str) {
    println!("{}", s);
}
let owned = String::from("ahoj");
prijmi_str(&owned);    // String sa automaticky konvertuje na &str
prijmi_str("ahoj");    // &str funguje priamo

Zlaté pravidlo pre funkcie:

  • Parametre píš ako &str — prijmeš aj String aj &str
  • Návratové hodnoty a polia v štruktúrach píš ako String — vlastníš dáta
// DOBRÉ — parameter &str prijme oboje
fn pozdrav(meno: &str) -> String {
    format!("Ahoj, {}!", meno)
}
pozdrav("Anna");                        // &str → OK
pozdrav(&String::from("Boris"));        // &String → OK
pozdrav(&"Cyril".to_string());          // &String → OK

// ZLÉ — parameter String núti volajúceho robiť konverziu
fn pozdrav_zle(meno: String) -> String {
    format!("Ahoj, {}!", meno)
}
// pozdrav_zle("Anna");  // CHYBA — &str nie je String
pozdrav_zle("Anna".to_string());  // musíš konvertovať

Úlohy 3

3a. Napíš funkciu dlzka(text: &str) -> usize ktorá vráti dĺžku. Zavolaj ju s &str aj so String.

3b. Napíš funkciu opakuj(text: &str, n: usize) -> String ktorá vráti text zopakovaný n-krát.

3c. Čo je zle? Oprav:

fn prvych_5(text: String) -> String {
    text[..5].to_string()
}
prvych_5("ahoj svet");

Kapitola 4: Modifikácia String

String je meniteľný. Tu sú všetky spôsoby ako ho meniť:

Pridávanie

let mut s = String::from("ahoj");

// push_str — pridaj &str na koniec
s.push_str(" svet");     // "ahoj svet"

// push — pridaj jeden char
s.push('!');              // "ahoj svet!"

// + operátor — spája String + &str (konzumuje prvý!)
let a = String::from("ahoj");
let b = String::from(" svet");
let c = a + &b;           // c = "ahoj svet", a JE ZKONZUMOVANÝ!
// println!("{}", a);      // CHYBA — a bolo presunuté do c

// format! — bezpečná konkatenácia (nekonzumuje nič)
let a = String::from("ahoj");
let b = String::from("svet");
let c = format!("{} {}", a, b);  // c = "ahoj svet"
println!("{}", a);               // OK — a stále existuje

Mazanie

let mut s = String::from("ahoj svet");

// clear — vymaž všetko
s.clear();               // ""

let mut s = String::from("ahoj svet");

// truncate — skráť na N bajtov
s.truncate(4);           // "ahoj"

let mut s = String::from("ahoj");

// pop — odstráň posledný char, vráti Option<char>
let posledny = s.pop();  // Some('j'), s = "aho"

Nahradenie

let s = String::from("ahoj svet ahoj");

// replace — nahraď všetky výskyty (vráti nový String)
let novy = s.replace("ahoj", "čau");
// "čau svet čau"

// replacen — nahraď len prvých N výskytov
let novy = s.replacen("ahoj", "čau", 1);
// "čau svet ahoj"

Dôležité: replace vracia nový String, nemení pôvodný.

Úlohy 4

4a. Vytvor String "Rust je super". Pridaj na koniec " jazyk!". Pridaj na koniec '🦀'. Vypíš výsledok.

4b. Máš String "ahoj_svet_rust". Nahraď všetky _ medzerou. Vypíš.

4c. Máš String. Postupne z neho popuj znaky kým nie je prázdny. Každý vypíš.

4d. Čo je zle? Oprav (2 spôsoby):

let a = String::from("ahoj");
let b = String::from(" svet");
let c = a + &b;
println!("{}", a);  // chyba!

Kapitola 5: char — jeden znak

char v Ruste je 4 bajty a reprezentuje jeden Unicode bod (nie bajt!).

let c: char = 'a';
let emoji: char = '🦀';
let slovak: char = 'ž';

// Kontroly
c.is_alphabetic();     // true — je písmeno?
c.is_numeric();        // false — je číslica?
c.is_alphanumeric();   // true — písmeno alebo číslica?
c.is_uppercase();      // false
c.is_lowercase();      // true
c.is_whitespace();     // false — je medzera/tab/newline?
c.is_ascii();          // true — je ASCII (0-127)?

// Konverzia veľkosť
c.to_uppercase();      // iterátor! nie char (lebo 'ß' → "SS")
c.to_lowercase();      // iterátor!
c.to_ascii_uppercase(); // char — len pre ASCII znaky
c.to_ascii_lowercase(); // char

// char → String
let s: String = c.to_string();        // "a"
let s: String = String::from(c);      // "a"

// char → u32 (Unicode code point)
let kod: u32 = c as u32;              // 97

// u32 → char (ak je platný Unicode)
let c: Option<char> = char::from_u32(97);  // Some('a')

Dôležité o to_uppercase/to_lowercase:

// to_uppercase vráti iterátor, nie char!
// Lebo niektoré znaky sa mapujú na viac znakov: ß → SS
let velke: String = 'a'.to_uppercase().collect();  // "A"
let velke: String = 'ß'.to_uppercase().collect();  // "SS"

// Pre jednoduché ASCII použi to_ascii_uppercase — vráti char
let velke: char = 'a'.to_ascii_uppercase();  // 'A'

Úlohy 5

5a. Napíš funkciu je_samohláska(c: char) -> bool — true pre a, e, i, o, u (aj veľké). Použi to_ascii_lowercase() a matches! alebo porovnávanie.

5b. Napíš funkciu pocet_cifier(text: &str) -> usize — koľko znakov v texte sú číslice. Použi .chars() a .is_numeric().

5c. Napíš funkciu velkymi(text: &str) -> String — celý text veľkými písmenami. Použi .chars(), .to_ascii_uppercase(), .collect().

5d. Čo vráti?

println!("{}", 'A'.is_uppercase());
println!("{}", '5'.is_numeric());
println!("{}", ' '.is_whitespace());
println!("{}", 'ž'.is_ascii());
println!("{}", 'ž'.is_alphabetic());

Kapitola 6: Iterácia cez znaky — chars()

String v Ruste je UTF-8. Jeden znak môže byť 14 bajty. Preto nemôžeš indexovať s[0] — nevieš koľko bajtov má znak.

let text = "ahoj";

// chars() — iterátor cez char hodnoty
for c in text.chars() {
    println!("{}", c);  // a, h, o, j
}

// Počet znakov
let pocet: usize = text.chars().count();  // 4

// Do Vec<char>
let znaky: Vec<char> = text.chars().collect();
// ['a', 'h', 'o', 'j']

// N-tý znak
let druhy: Option<char> = text.chars().nth(1);  // Some('h')

// Prvý znak
let prvy: Option<char> = text.chars().next();    // Some('a')

// Posledný znak
let posledny: Option<char> = text.chars().last(); // Some('j')

Pozor na .len() vs .chars().count():

let text = "žaba";
println!("{}", text.len());            // 5 (bajtov! 'ž' = 2 bajty)
println!("{}", text.chars().count());  // 4 (znakov)

// Pre čisto ASCII texty sú rovnaké
let text = "ahoj";
println!("{}", text.len());            // 4
println!("{}", text.chars().count());  // 4

chars() s iterátorovými metódami

let text = "Ahoj Svet 123";

// filter — len písmená
let pismena: String = text.chars().filter(|c| c.is_alphabetic()).collect();
// "AhojSvet"

// map — na veľké
let velke: String = text.chars().map(|c| c.to_ascii_uppercase()).collect();
// "AHOJ SVET 123"

// any — obsahuje číslicu?
let ma_cislo: bool = text.chars().any(|c| c.is_numeric());
// true

// all — sú všetky písmená?
let vsetky_pismena: bool = text.chars().all(|c| c.is_alphabetic());
// false

// enumerate — index + znak
for (i, c) in text.chars().enumerate() {
    println!("{}: {}", i, c);
}

// take — prvých N znakov
let prvych_4: String = text.chars().take(4).collect();
// "Ahoj"

// skip — preskoč prvých N znakov
let od_5: String = text.chars().skip(5).collect();
// "Svet 123"

Úlohy 6

6a. Napíš funkciu prevrat(text: &str) -> String — obráti text. Použi .chars().rev().collect().

6b. Napíš funkciu je_palindrom(text: &str) -> bool — true ak sa text rovná sám sebe pozadu. Ignoruj veľkosť písmen.

6c. Napíš funkciu censuruj(text: &str, zakazane: &[char]) -> String — nahraď zakázané znaky hviezdičkou '*'. Použi .chars().map().collect().

6d. Napíš funkciu prvych_n_znakov(text: &str, n: usize) -> String. Použi .chars().take(n).collect().

6e. Napíš funkciu pocet_slov(text: &str) -> usize. Použi .split_whitespace().count().


Kapitola 7: Rozdeľovanie reťazcov — split, lines, split_whitespace

split_whitespace — rozdeľ podľa medzier

let text = "  ahoj   svet   rust  ";

let slova: Vec<&str> = text.split_whitespace().collect();
// ["ahoj", "svet", "rust"] — medzery na okrajoch a duplikáty ignorované

split — rozdeľ podľa oddeľovača

let text = "anna,boris,cyril";

// Podľa znaku
let mena: Vec<&str> = text.split(',').collect();
// ["anna", "boris", "cyril"]

// Podľa reťazca
let text = "ahoj--svet--rust";
let casti: Vec<&str> = text.split("--").collect();
// ["ahoj", "svet", "rust"]

// splitn — maximálne N častí
let text = "a:b:c:d:e";
let casti: Vec<&str> = text.splitn(3, ':').collect();
// ["a", "b", "c:d:e"] — rozdelí len na prvých 2 dvojbodkách

lines — rozdeľ podľa riadkov

let text = "prvý riadok\ndruhý riadok\ntretí riadok";

for riadok in text.lines() {
    println!("{}", riadok);
}
// prvý riadok
// druhý riadok
// tretí riadok

Úlohy 7

7a. Máš CSV riadok "Anna,25,Bratislava". Rozdeľ ho na časti. Vypíš meno, vek, mesto.

7b. Napíš funkciu pocet_slov(text: &str) -> usize. Použi split_whitespace.

7c. Máš viacriadkový text. Nájdi najdlhší riadok. Použi .lines() a .max_by_key().

7d. Máš cestu "/home/user/docs/file.txt". Rozdeľ podľa /. Vypíš posledný kúsok (filename).


Kapitola 8: Hľadanie v reťazcoch

let text = "Ahoj svet, ahoj Rust!";

// contains — obsahuje podreťazec?
text.contains("svet");       // true
text.contains("Python");     // false

// starts_with / ends_with
text.starts_with("Ahoj");    // true
text.ends_with("!");          // true
text.ends_with("Rust");      // false (končí na "!")

// find — index prvého výskytu (v bajtoch!)
text.find("svet");           // Some(5)
text.find("Python");         // None

// rfind — od konca
text.rfind("ahoj");          // Some(11)

// matches — iterátor cez všetky výskyty
let pocet = text.matches("ahoj").count();  // 1 (case-sensitive!)
let pocet = text.to_lowercase().matches("ahoj").count();  // 2

Úlohy 8

8a. Napíš funkciu obsahuje_cislicu(text: &str) -> bool — true ak text obsahuje aspoň jednu číslicu. Použi .chars().any().

8b. Napíš funkciu pocet_vyskytu(text: &str, hladany: &str) -> usize. Použi .matches().count().

8c. Napíš funkciu zacina_velkym(text: &str) -> bool — true ak prvý znak je veľké písmeno.

8d. Máš vektor reťazcov. Vyfiltruj len tie, ktoré obsahujú slovo "rust" (case-insensitive).


Kapitola 9: Trimovanie a padding

trim — odstráň biele znaky z okrajov

let text = "  ahoj svet  \n";

text.trim();          // "ahoj svet"
text.trim_start();    // "ahoj svet  \n"
text.trim_end();      // "  ahoj svet"

// trim_matches — odstráň konkrétne znaky
let text = "---ahoj---";
text.trim_matches('-');  // "ahoj"

let text = "***ahoj***svet***";
text.trim_matches('*');  // "ahoj***svet"  (len okraje!)

Padding / zarovnanie (nie metóda, ale format!)

let meno = "Anna";

// Zarovnanie vpravo (šírka 10)
let s = format!("{:>10}", meno);   // "      Anna"

// Zarovnanie vľavo
let s = format!("{:<10}", meno);   // "Anna      "

// Na stred
let s = format!("{:^10}", meno);   // "   Anna   "

// S vlastným znakom
let s = format!("{:*>10}", meno);  // "******Anna"
let s = format!("{:-^10}", meno);  // "---Anna---"

Úlohy 9

9a. Máš vstup od používateľa " ahoj \n". Očisti ho trimom. Potom over, či je "ahoj".

9b. Máš vektor mien rôznej dĺžky. Vypíš ich zarovnané vpravo na šírku 15 znakov:

          Anna
         Boris
         Cyril

9c. Napíš funkciu ocisti(text: &str) -> String — trim + nahraď viacnásobné medzery jednou. Hint: split_whitespace().collect::<Vec<&str>>().join(" ").


Kapitola 10: Slicing — &str z časti String

Môžeš vziať kúsok reťazca ako &str. Ale pozor — indexy sú v bajtoch, nie znakoch!

let text = "ahoj svet";

// Slice podľa rozsahu bajtov
let slice: &str = &text[0..4];    // "ahoj"
let slice: &str = &text[5..];     // "svet"
let slice: &str = &text[..4];     // "ahoj"

// NEBEZPEČNÉ pre non-ASCII!
let text = "žaba";
// &text[0..1]  // PANIC! 'ž' je 2 bajty, toto by rozdelilo uprostred znaku!
// &text[0..2]  // OK — "ž"

Bezpečný spôsob pre ľubovoľný text:

// Použi chars() namiesto slicingu
fn prvy_znak(text: &str) -> Option<char> {
    text.chars().next()
}

fn prvych_n(text: &str, n: usize) -> String {
    text.chars().take(n).collect()
}

fn od_znaku_n(text: &str, n: usize) -> String {
    text.chars().skip(n).collect()
}

fn podretazec(text: &str, od: usize, do_: usize) -> String {
    text.chars().skip(od).take(do_ - od).collect()
}

Kedy je slice bezpečný:

  • Ak vieš, že text je čistý ASCII (anglická abeceda, čísla)
  • Ak index získaš z .find() (ten vracia bajtový index)
let text = "ahoj svet rust";
if let Some(pos) = text.find("svet") {
    let od_svet: &str = &text[pos..];  // "svet rust" — bezpečné, find vrátil správny index
}

Úlohy 10

10a. Máš ASCII text "Hello World". Vyber prvých 5 znakov slicingom. Vyber posledných 5.

10b. Napíš funkciu bezpecne_prvych_n(text: &str, n: usize) -> String — vráti prvých N znakov bez paniki (aj pre non-ASCII).

10c. Máš text. Nájdi pozíciu prvej medzery pomocou .find(' '). Ak existuje, vráť prvé slovo ako &str slice:

fn prve_slovo(text: &str) -> &str

10d. Prečo toto panikne? Ako to opravíš?

let text = "café";
let slice = &text[0..4];

Kapitola 11: Parsovanie — z reťazca na iné typy

// &str / String → číslo (.parse())
let cislo: i32 = "42".parse().unwrap();           // 42
let cislo: f64 = "3.14".parse().unwrap();         // 3.14
let cislo: Result<i32, _> = "nie_cislo".parse();  // Err(...)

// Bezpečné parsovanie
let vstup = "42";
match vstup.parse::<i32>() {
    Ok(n) => println!("Číslo: {}", n),
    Err(_) => println!("Nie je číslo"),
}

// Alebo s .ok()
let cislo: Option<i32> = vstup.parse().ok();

// číslo → String
let text: String = 42.to_string();
let text: String = format!("{}", 42);

// bool
let b: bool = "true".parse().unwrap();   // true
let b: bool = "false".parse().unwrap();  // false

Úlohy 11

11a. Napíš funkciu parsuj_cisla(text: &str) -> Vec<i32> — text obsahuje čísla oddelené čiarkami ("1,2,3,4,5"). Rozdeľ a sparsuj. Ignoruj neplatné hodnoty.

11b. Napíš funkciu parsuj_csv_riadok(riadok: &str) -> Option<(String, u32, f64)>: Vstup: "Anna,25,1.5"Some(("Anna".to_string(), 25, 1.5)) Ak parsovanie zlyhá → None.

11c. Máš vstup od používateľa (String). Trim ho, parsuj na u32. Ak sa nepodarí, vyskúšaj f64. Ak ani to, vráť chybu.


Kapitola 12: Pokročilé operácie

repeat — opakuj reťazec

let s = "ha".repeat(3);   // "hahaha"
let s = "-".repeat(20);   // "--------------------"

to_lowercase / to_uppercase

let text = "Ahoj Svet";
let male: String = text.to_lowercase();     // "ahoj svet"
let velke: String = text.to_uppercase();     // "AHOJ SVET"

// Porovnanie case-insensitive
fn rovnake_ci(a: &str, b: &str) -> bool {
    a.to_lowercase() == b.to_lowercase()
}
rovnake_ci("Ahoj", "AHOJ");  // true

char_indices — indexy aj znaky

let text = "žaba";

// char_indices dáva (bajtový_index, char)
for (i, c) in text.char_indices() {
    println!("bajt {}: {}", i, c);
}
// bajt 0: ž
// bajt 2: a    (ž zabrala 2 bajty!)
// bajt 3: b
// bajt 4: a

Collect medzi typmi

// Vec<char> → String
let znaky = vec!['a', 'h', 'o', 'j'];
let text: String = znaky.into_iter().collect();
// "ahoj"

// Vec<&str> → String (s oddeľovačom)
let slova = vec!["ahoj", "svet"];
let text: String = slova.join(" ");
// "ahoj svet"

// Vec<String> → String (s oddeľovačom)
let slova: Vec<String> = vec!["ahoj".into(), "svet".into()];
let text: String = slova.join(", ");
// "ahoj, svet"

// Iterátor &str → String
let text: String = ["ahoj", "svet"].iter().copied().collect::<Vec<&str>>().join(" ");

// S itertools je jednoduchšie:
// use itertools::Itertools;
// let text = ["ahoj", "svet"].iter().join(" ");

Úlohy 12

12a. Napíš funkciu oddelovac(sirka: usize) -> String — vráti riadok pomlčiek danej šírky.

12b. Napíš funkciu kapitalizuj(text: &str) -> String — prvé písmeno veľké, zvyšok malé. Hint: .chars().next() pre prvé, .chars().skip(1) pre zvyšok.

12c. Napíš funkciu snake_to_camel(text: &str) -> String — preveď "ahoj_svet_rust" na "AhojSvetRust". Hint: split podľa _, každé slovo kapitalizuj, spoj.

12d. Napíš funkciu je_platny_email(text: &str) -> bool:

  • Obsahuje presne jednu @
  • Pred @ je aspoň 1 znak
  • Za @ je aspoň 3 znaky
  • Za @ obsahuje .

Kapitola 13: Vzory zo skúšky

Vzor 1: Display pre štruktúru/enum

use std::fmt;

enum Stav { Novy, Aktivny, Dokonceny }

impl fmt::Display for Stav {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Stav::Novy => write!(f, "Nový"),
            Stav::Aktivny => write!(f, "Aktívny"),
            Stav::Dokonceny => write!(f, "Dokončený"),
        }
    }
}

struct Uloha { nazov: String, stav: Stav }

impl fmt::Display for Uloha {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} [{}]", self.nazov, self.stav)
    }
}
// Výstup: "Upratovanie [Nový]"

Vzor 2: Obesenec — zobrazenie skrytého slova

fn zobraz_slovo(slovo: &str, uhadnute: &HashSet<char>) -> String {
    slovo.chars().map(|c| {
        if uhadnute.contains(&c) { c } else { '_' }
    }).collect()
}
// zobraz_slovo("ahoj", &{'a', 'o'}) → "a_o_"

Vzor 3: Parsovanie vstupu od používateľa

fn nacitaj_cislo() -> Option<u32> {
    let mut vstup = String::new();
    std::io::stdin().read_line(&mut vstup).ok()?;
    vstup.trim().parse().ok()
}

Vzor 4: CSV / JSON parsovanie

fn parsuj_knihu(riadok: &str) -> Option<Kniha> {
    let casti: Vec<&str> = riadok.split(',').collect();
    if casti.len() != 3 { return None; }
    let rok: u16 = casti[2].trim().parse().ok()?;
    Some(Kniha {
        nazov: casti[0].trim().to_string(),
        autor: casti[1].trim().to_string(),
        rok,
    })
}

Úlohy 13

13a. Implementuj Display pre enum Priorita { Nizka, Stredna, Vysoka } — výstup: "Nízka", "Stredná", "Vysoká".

13b. Implementuj Display pre štruktúru Zamestnanec { meno: String, pozicia: String, plat: u32 } vo formáte "Anna (Programátor) - 3000€".

13c. Napíš funkciu, ktorá načíta riadok z stdin, trimne ho a vráti. Ak je prázdny po trime, vráti None:

fn nacitaj_riadok() -> Option<String>

13d. Napíš funkciu, ktorá sparsuje text "meno:vek:mesto" na tuple:

fn parsuj(text: &str) -> Option<(String, u32, String)>

Prehľad konverzií

&str ──.to_string()──→ String
&str ──.to_owned()───→ String
&str ──String::from()─→ String

String ──&──────────→ &str
String ──.as_str()──→ &str

char ──.to_string()─→ String
char ──String::from()→ String

&str ──.chars()─────→ Iterator<char>
String ──.chars()───→ Iterator<char>

Iterator<char> ──.collect()──→ String
Vec<char> ──.iter().collect()→ String

&str ──.parse::<T>()──→ Result<T, Error>
T ──.to_string()───────→ String  (ak T: Display)

&str ──.as_bytes()────→ &[u8]