From
とInto
From
トレイトとInto
トレイトは本質的に結びついており、そのことが実際の実装に反映されています。もし型Aが型Bからの型変換をサポートしているのであれば、型Bは型Aへの型変換ができると思うのが自然です。
From
From
トレイトは、ある型に対し、別の型からその型を作る方法を定義できるようにするものです。そのため、複数の型の間で型変換を行うための非常にシンプルな仕組みを提供しています。標準ライブラリでは、基本データ型やよく使われる型に対して、このトレイトが多数実装されています。
例えば、str
からString
への型変換は簡単です。
#![allow(unused)] fn main() { let my_str = "hello"; let my_string = String::from(my_str); }
自作の型に対しても、型変換を定義すれば同じように行えます。
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; // ここの型アノテーションを消してみましょう。 let num: Number = int.into(); println!("My number is {:?}", num); }
From
and Into
are interchangable
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); }