Ce face Cow
Cow<str> este fie Cow::Borrowed(&str), fie Cow::Owned(String). Este util pentru funcții care de cele mai multe ori returnează textul primit neschimbat și doar uneori trebuie să creeze unul nou: în cazul obișnuit nu se alocă nimic.
Se folosește ca un &str obișnuit (prin Deref): îl poți afișa, compara, apela metode pe el. to_mut() îți dă acces de modificare, transformând împrumutul în valoare deținută doar la nevoie; into_owned() îți dă String-ul. String::from_utf8_lossy este un exemplu din std care returnează Cow<str>.
Parametri
| Parametru | Descriere |
|---|---|
Borrowed(&B) |
Varianta fără copiere. |
Owned(B::Owned) |
Varianta cu valoare proprie (String pentru str, Vec<T> pentru [T]). |
Ce returnează
Un Cow; into_owned() returnează valoarea deținută, to_mut() o referință mutabilă la ea.
Exemple
Exemplul 1: Corectarea diacriticelor doar când e nevoie
Textele corecte trec fără nicio copiere; doar cele cu s/t cu sedilă (U+015F, U+0163) produc un String nou.
use std::borrow::Cow;
fn corecteaza(text: &str) -> Cow<'_, str> {
if text.contains(['\u{015F}', '\u{0163}']) {
Cow::Owned(text.replace('\u{015F}', "ș").replace('\u{0163}', "ț"))
} else {
Cow::Borrowed(text)
}
}
fn main() {
let texte = ["Brașov", "Bra\u{015F}ov", "Galați", "Gala\u{0163}i"];
for t in texte {
let r = corecteaza(t);
let tip = match r {
Cow::Borrowed(_) => "împrumutat",
Cow::Owned(_) => "copie nouă",
};
println!("{r} ({tip})");
}
}
Rezultat
Brașov (împrumutat)
Brașov (copie nouă)
Galați (împrumutat)
Galați (copie nouă)
Exemplul 2: to_mut și into_owned
use std::borrow::Cow;
fn main() {
let note = [7, 9, 10];
let mut c: Cow<[i32]> = Cow::Borrowed(¬e);
println!("înainte: {:?}, împrumutat: {}", c, matches!(c, Cow::Borrowed(_)));
c.to_mut().push(8); // acum se face copia
println!("după: {:?}, împrumutat: {}", c, matches!(c, Cow::Borrowed(_)));
let v: Vec<i32> = c.into_owned();
println!("vector: {v:?}, originalul: {note:?}");
}
Rezultat
înainte: [7, 9, 10], împrumutat: true
după: [7, 9, 10, 8], împrumutat: false
vector: [7, 9, 10, 8], originalul: [7, 9, 10]
Greșeli frecvente
- Returnezi mereu
Cow::Owned: pierzi singurul avantaj al luiCow. FoloseșteBorrowedcând datele nu se schimbă. - Uiți durata de viață în semnătură:
fn f(s: &str) -> Cow<str>dă avertismentulhiding a lifetime that's elided elsewhere is confusing(eroare cu-D warnings); scrieCow<'_, str>, ca să se vadă că rezultatul împrumută din parametru.
Comenzi înrudite
String::from_utf8: Creează un String din octeți: from_utf8 verifică UTF-8 și dă eroare; from_utf8_lossy înlocuiește octeții greșiți cu �.str::to_string: Copiază un &str într-un String nou, deținut. to_string și to_owned dau același rezultat.Clone: Trait-ul pentru copierea explicită a unei valori cu .clone(); se obține cu #[derive(Clone)] sau implementare manuală.Deref: Trait-ul din spatele operatorului * și al conversiei automate &Box<T> -> &T, &String -> &str (deref coercion).