Ce face AsRef
AsRef<T> înseamnă „din mine poți obține ieftin un &T”. String, &str și Box<str> implementează AsRef<str>; Vec<T> și tablourile implementează AsRef<[T]>; String, &str, PathBuf și &Path implementează AsRef<Path>.
Așa sunt scrise funcțiile din std::fs: fs::read_to_string<P: AsRef<Path>>(path: P) primește orice fel de cale. În funcțiile tale îl folosești la fel: parametrul generic, apoi .as_ref() în corp. Conversia nu copiază nimic; spre deosebire de Into, nu creează o valoare nouă.
Ce returnează
as_ref() returnează &T.
Exemple
Exemplul 1: O funcție pentru orice fel de text
fn numar_cuvinte<S: AsRef<str>>(text: S) -> usize {
text.as_ref().split_whitespace().count()
}
fn main() {
let deținut = String::from("Ana are mere și pere");
println!("{}", numar_cuvinte("Bună ziua, Iași"));
println!("{}", numar_cuvinte(&deținut));
println!("{}", numar_cuvinte(deținut));
}
Rezultat
3
5
5
Exemplul 2: Căi și felii
use std::path::{Path, PathBuf};
fn extensie<P: AsRef<Path>>(cale: P) -> String {
match cale.as_ref().extension() {
Some(e) => e.to_string_lossy().into_owned(),
None => String::from("(fără)"),
}
}
fn suma<V: AsRef<[u32]>>(valori: V) -> u32 {
valori.as_ref().iter().sum()
}
fn main() {
println!("{}", extensie("raport.pdf"));
println!("{}", extensie(String::from("poze/vara.jpg")));
println!("{}", extensie(PathBuf::from("/etc/hosts")));
println!("{} {}", suma([1, 2, 3]), suma(vec![10, 20]));
}
Rezultat
pdf
jpg
(fără)
6 30
Greșeli frecvente
- Folosești
AsRefcând ai nevoie de o valoare deținută.as_refdă doar o referință; pentru o valoare nouă foloseșteInto. - Te aștepți ca
AsRefsă fie folosit automat caDeref. Nu este: trebuie să apelezi explicit.as_ref().
Comenzi înrudite
Into: Perechea lui From văzută din partea sursei: x.into() convertește în tipul cerut; util în parametri generici.Deref: Trait-ul din spatele operatorului * și al conversiei automate &Box<T> -> &T, &String -> &str (deref coercion).From: Trait-ul pentru conversii care nu pot eșua: Tinta::from(x). Implementându-l, primești gratuit și x.into().