FromとInto - Rust By Example
Description: Rust by Example (RBE) is a collection of runnable examples that illustrate various Rust concepts and standard libraries.

## Keyboard shortcuts

Press `←` or `→` to navigate between chapters

Press `S` or `/` to search in the book

Press `?` to show this help

Press `Esc` to hide this help

# `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);
    }

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`

`Into`トレイトは、単に`From`トレイトの逆の働きをし、ある型を他の型に変換する方法を定義します。

`into()` の呼び出し時にはほとんどの場合戻り値の型をコンパイラが決定できません。そのため戻り値の型は明示的に指定する必要があります。

    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 interchangeable

`From` と `Into` は相補的にデザインされているので両方のトレイトを実装する必要はありません。`From` トレイトを実装すれば、 `Into` は必要なときに呼ばれます。ただし、逆は真ではない点に注意してください。 `Into` が実装されていても、 `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);
    }