From
and Into
The From
and Into
traits are inherently linked, and this is actually part of
its implementation. If you are able to convert type A from type B, then it
should be easy to believe that we should be able to convert type B to type A.
From
The From
trait allows for a type to define how to create itself from another
type, hence providing a very simple mechanism for converting between several
types. There are numerous implementations of this trait within the standard
library for conversion of primitive and common types.
For example we can easily convert a str
into a String
#![allow(unused)] fn main() { let my_str = "hello"; let my_string = String::from(my_str); }
We can do something similar for defining a conversion for our own type.
use std::convert::From; #[derive(Debug)] struct Number { value: i32, } impl From<i32> for Number { fn from(item: i32) -> Self { Number { value: item } } } fn main() { let num = Number::from(30); println!("My number is {:?}", num); }
Into
The Into
trait is simply the reciprocal of the From
trait. It
defines how to convert a type into another type.
Calling into()
typically requires us to specify the result type as the compiler is unable to determine this most of the time.
use std::convert::Into; #[derive(Debug)] struct Number { value: i32, } impl Into<Number> for i32 { fn into(self) -> Number { Number { value: self } } } fn main() { let int = 5; // Try removing the type annotation let num: Number = int.into(); println!("My number is {:?}", num); }
From
and Into
are interchangeable
From
and Into
are designed to be complementary.
We do not need to provide an implementation for both traits.
If you have implemented the From
trait for your type, Into
will call it
when necessary. Note, however, that the converse is not true: implementing Into
for your type will not automatically provide it with an implementation of From
.
use std::convert::From; #[derive(Debug)] struct Number { value: i32, } // Define `From` impl From<i32> for Number { fn from(item: i32) -> Self { Number { value: item } } } fn main() { let int = 5; // use `Into` let num: Number = int.into(); println!("My number is {:?}", num); }