Ce face TryFrom
TryFrom este varianta lui From pentru conversii care nu reușesc mereu: un i32 negativ nu încape într-un u32, un număr nu este mereu o notă validă. try_from returnează Ok(valoare) sau Err(eroare), iar tipul erorii se alege prin type Error.
La fel ca la From/Into, implementarea lui TryFrom îți dă automat TryInto, deci poți scrie let n: u8 = x.try_into()?;. Ambele trait-uri sunt în preludiul ediției 2021+, deci nu trebuie importate. Pentru numere, try_from este alternativa sigură la as, care taie valoarea pe tăcute.
Parametri
| Parametru | Descriere |
|---|---|
type Error |
Tipul erorii returnate când conversia eșuează. |
try_from(v) |
Conversia propriu-zisă. |
Ce returnează
Result<Tinta, Error>.
Exemple
Exemplul 1: Numere care pot să nu încapă
fn main() {
println!("{:?}", u8::try_from(200_i32));
println!("{:?}", u8::try_from(300_i32));
println!("{:?}", u32::try_from(-5_i64));
let mare: i64 = 70_000;
let r: Result<u16, _> = mare.try_into();
match r {
Ok(v) => println!("încape: {v}"),
Err(e) => println!("eroare: {e}"),
}
println!("cu as (taie pe tăcute): {}", mare as u16);
}
Rezultat
Ok(200)
Err(TryFromIntError(PosOverflow))
Err(TryFromIntError(NegOverflow))
eroare: number too large to fit in target type
cu as (taie pe tăcute): 4464
Exemplul 2: O notă școlară validă
#[derive(Debug)]
struct Nota(u8);
impl TryFrom<i32> for Nota {
type Error = String;
fn try_from(v: i32) -> Result<Self, Self::Error> {
if (1..=10).contains(&v) {
Ok(Nota(v as u8))
} else {
Err(format!("{v} nu este o notă între 1 și 10"))
}
}
}
fn main() {
for v in [9, 0, 11] {
match Nota::try_from(v) {
Ok(n) => println!("ok: {n:?}, valoare {}", n.0),
Err(e) => println!("eroare: {e}"),
}
}
let n: Result<Nota, _> = 7.try_into();
println!("{n:?}");
}
Rezultat
ok: Nota(9), valoare 9
eroare: 0 nu este o notă între 1 și 10
eroare: 11 nu este o notă între 1 și 10
Ok(Nota(7))
Greșeli frecvente
- Folosești
aspentru conversii între tipuri numerice cu valori venite din afară:300 as u8dă 44, fără eroare.u8::try_from(300)îți spune că nu încape. - Implementezi și
TryFrom, șiFrompentru aceeași pereche: Rust are deja unTryFromautomat pentru oriceFrom(cu eroareaInfallible), deci apare conflict.
Comenzi înrudite
From: Trait-ul pentru conversii care nu pot eșua: Tinta::from(x). Implementându-l, primești gratuit și x.into().Into: Perechea lui From văzută din partea sursei: x.into() convertește în tipul cerut; util în parametri generici.FromStr: Trait-ul care face un tip „citibil” din text; după implementare, „…”.parse::<Tip>() funcționează.char::from_u32: Creează un char din codul lui Unicode, dacă este valid; altfel returnează None.