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

Intoトレイトは、単にFromトレイトの逆の働きをします。もし自作の型にFromトレイトが実装されていたら、Intoは必要に応じてそれを呼び出します。

Intoトレイトを使用すると、ほとんどの場合、コンパイラが型を決定することができないため、変換する型を指定する必要があります。しかし、この機能を無料で得られることを考えれば、これは小さなトレードオフです。

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 int = 5;
    // Try removing the type annotation
    // ここの型アノテーションを消してみましょう。
    let num: Number = int.into();
    println!("My number is {:?}", num);
}