16.3 Safe, Infallible Conversions: From and Into
The From<T> and Into<U> traits represent conversions that are guaranteed to succeed, meaning they are infallible. This contrasts with conversions that might fail, such as narrowing an integer (i32 to i8), which are handled by the TryFrom/TryInto traits (covered in Section 16.4). From/Into are the idiomatic Rust way to express a safe and unambiguous transformation from one type to another. Crucially, for conversions where success cannot be guaranteed (like i32 to u8), the From trait is deliberately not implemented in the standard library. This forces the programmer to choose an alternative: either the safe, error-handling approach with TryFrom, or an explicit, potentially lossy cast using as.
impl From<T> for Udefines how to create aUinstance from aTinstance.- If 
From<T>is implemented forU, the compiler automatically provides an implementation ofInto<U>forT. This works because the standard library includes a generic implementation conceptually similar toimpl<T, U> Into<U> for T where U: From<T> { fn into(self) -> U { U::from(self) } }. Essentially, calling.into()on a value of typeTdelegates the conversion to theU::from(t)implementation. 
Conversion can be invoked via U::from(value_t) or value_t.into(). The into() method relies on type inference; the compiler must be able to determine the target type U from the context (e.g., variable type annotation).
16.3.1 Standard Library Examples
The standard library provides numerous From implementations for common, safe conversions:
fn main() { // Integer widening (always safe) let val_u8: u8 = 100; let val_i32 = i32::from(val_u8); // Explicit call to from() let val_u16: u16 = val_u8.into(); // into() infers target type from variable declaration println!("u8: {}, converted to i32: {}, converted to u16: {}", val_u8, val_i32, val_u16); // String conversions let message_slice = "Hello from slice"; let message_string = String::from(message_slice); // Canonical way to create owned String from &str let message_string_again: String = message_slice.into(); // Also works due to From<&str> for String println!("Owned string: {}", message_string); println!("Owned string (via into): {}", message_string_again); // Creating collections // Here, [1, 2, 3] is an array literal of type [i32; 3] let vec_from_array = Vec::from([1, 2, 3]); // Convert the Vec<i32> into an owned slice Box<[i32]> // Vec<T> can be converted into Box<[T]> and vice versa via From/Into. // Note: [i32] is a dynamically sized slice type; Box<[i32]> owns it. let boxed_slice: Box<[i32]> = vec_from_array.into(); println!("Boxed slice: {:?}", boxed_slice); }
16.3.2 Implementing From for Custom Types
Implement From to define standard, safe conversions for your own data structures:
#[derive(Debug)] struct Point3D { x: i64, y: i64, z: i64, } // Allow creating a Point3D from a tuple (i64, i64, i64) impl From<(i64, i64, i64)> for Point3D { fn from(tuple: (i64, i64, i64)) -> Self { Point3D { x: tuple.0, y: tuple.1, z: tuple.2 } } } // Allow creating a Point3D from an array [i64; 3] impl From<[i64; 3]> for Point3D { fn from(arr: [i64; 3]) -> Self { Point3D { x: arr[0], y: arr[1], z: arr[2] } } } fn main() { let p1 = Point3D::from((10, -20, 30)); let p2: Point3D = [40, 50, 60].into(); // Type inference works here println!("p1: {:?}", p1); println!("p2: {:?}", p2); }
Using From/Into clearly signals that the conversion is a standard, safe, and lossless transformation for the involved types.