Pro vytvoření množiny z vektoru je efektivnější použít iterátor drain pro přenesení vlastnictví prvků vektoru místo jejich kopírování:
let mut v = vec!["podporucik", "inspektor", "praktikant", "tovarnik"]; let set1: HashSet<&str> = v.drain(..).collect();
Pozn.: kvůli lifetime nelze zapsat na jeden řádek, ale to by v budoucnu mohly zlepšit non-lexical lifetimes.
to vypada dobre, protoze ten vektor se stejne zahodi (bude prazdny ze?)
V pripade tech &str to znamenalo kopirovani ukazatelu na stringy nebo celych stringu. Asi to prvni, kdyz jsou to konstanty v RO (text segmentu)
(ptam se, protoze napriklad v Jave to nikdo moc neresi, jelikoz se kopiruji jen reference, takze typovy system Rustu je docela novinka pro nas lopataky :-) ).
Protože jsme v parametru drain dali celý rozsah, vektor přijde o vlastnictví všech prvků. Samotný vektor se dealokuje až skončí scope jeho vlastníka, tedy proměnné v. Jenže vektor řetězců (String) je jen pole ukazatelů na samotné řetězce. Samotné řetězce se vůbec nepřesunují ani nekopírují, jen je teď vlastní HashSet a ten vlastní proměnná set1.
V Rustu se téměř vždy defaultně kopírují jen reference (nebo struktury na zásobníku pokud typ implementuje copy trait), pro hlubokou kopii je potřeba zavolat explicitní clone() (nebo iterátor cloned a podobně), ať už volajícím, nebo volaným.
jasne, takze kdyz dam cele to let v do samostatneho bloku {}, tak mam dealokaci hned. Sice ta druha promenna bude nutne mut (naplnovat se bude v tom bloku), ale to by nemuselo vadit.
Další možnost je into_iter() iterátor. Ten vezme vlastnictví celého vektoru.
Díky za doplnění. Chystám se podobné ukázky dát do další části i s vysvětlením, aby to bylo kompletní,