16.4 Fallible Conversions with TryFrom
and TryInto
Not all conversions are guaranteed to succeed. Rust uses the TryFrom
and TryInto
traits for these cases, returning Result<T, E>
rather than a value that might silently overflow or otherwise fail.
16.4.1 Handling Conversion Failures
use std::convert::TryFrom; fn main() { let x: i8 = 127; let y = u8::try_from(x); // Ok(127) let z = u8::try_from(-1); // Err(TryFromIntError(())) println!("{:?}, {:?}", y, z); }
16.4.2 Implementing TryFrom
and TryInto
for Custom Types
You can define your own error type and logic when implementing TryFrom
:
use std::convert::TryFrom; use std::convert::TryInto; #[derive(Debug, PartialEq)] struct EvenNumber(i32); impl TryFrom<i32> for EvenNumber { type Error = String; fn try_from(value: i32) -> Result<Self, Self::Error> { if value % 2 == 0 { Ok(EvenNumber(value)) } else { Err(format!("{} is not an even number", value)) } } } fn main() { assert_eq!(EvenNumber::try_from(8), Ok(EvenNumber(8))); assert_eq!(EvenNumber::try_from(5), Err(String::from("5 is not an even number"))); let result: Result<EvenNumber, _> = 8i32.try_into(); assert_eq!(result, Ok(EvenNumber(8))); let result: Result<EvenNumber, _> = 5i32.try_into(); assert_eq!(result, Err(String::from("5 is not an even number"))); }