From & Into
Conversion from one type to another.
Derivable: ❌, without crates like derive_more.
When to implement: As-needed and convenient.
// Copyright 2025 Google LLC
// SPDX-License-Identifier: Apache-2.0
pub struct ObviousImplementation(String);
impl From<String> for ObviousImplementation {
fn from(value: String) -> Self {
ObviousImplementation(value)
}
}
impl From<&str> for ObviousImplementation {
fn from(value: &str) -> Self {
ObviousImplementation(value.to_owned())
}
}
fn main() {
// From String
let obvious1 = ObviousImplementation::from("Hello, obvious!".to_string());
// From &str
let obvious2 = ObviousImplementation::from("Hello, obvious!");
// A From implementation implies an Into implementation, &str.into() ->
// ObviousImplementation
let obvious3: ObviousImplementation = "Hello, implementation!".into();
}
-
The two traits exist to express different areas you’ll find conversion in codebases.
-
Fromprovides a constructor-style function, whereas into provides a method on an existing value. -
Prefer writing
From<T>implementations for a type you’re authoring instead ofInto<T>.The
Intotrait is implemented for any type that implementsFromautomatically.Intois preferred as a trait bound for arguments to functions for clarity of intent for what the function can take.T: Into<String>has clearer intent thanString: From<T>.