Chapter 03

Into<T> と From<T>

ほげさん
ほげさん
2023.02.28に更新
このチャプターの目次

このページでは Rust で頻出する変換処理を理解するために Into<T>From<T> についてまとめる。

Into<T>

Into<T> というトレイトを実装した型は intoT に変換できる。

convert/mod.rs
trait Into<T>: Sized {
  fn into(self) -> T;
}

たとえば &strStringInto<String> を実装しているので、どちらの型も into を実行すると String になる。

let string: String = string.into();
let string: String = str.into();

この Into<String> を引数にすると、引数が String でも &str でも動く処理を作れる。

fn main() {
    let string: String = "foo".to_string();
    let str: &str = "foo";

    something(string);
    something(str);
}

fn something<S: Into<String>>(s: S) {
    let string: String = s.into();
    println!("do something");
}

汎用的な処理 や、実行時は String しか渡せないけどテストコードでは &str を渡せると楽だ、みたいな場合に便利だ。

From<T>

From<T> というトレイトを実装した型は fromT から生成できる。

convert/mod.rs
trait From<T>: Sized {
  fn from(other: T) -> Self;
}

たとえば Ipv4Addr という標準ライブラリの型は From<[u8; 4]>From<u32> を実装しているので、[u8; 4]u32 のどちらからでも from で生成することができる。

let addr1 = Ipv4Addr::from([127, 0, 0, 1]);
let addr2 = Ipv4Addr::from(0x7f000001);

println!("{:?}", addr1);    // 127.0.0.1
println!("{:?}", addr2);    // 127.0.0.1

From<T> トレイトは Into<T> トレイトと対照的になっており、Into<T>From<T> があれば自動でコンパイラに実装してもらえる。

実際に Ipv4Addrinto でも生成できる。

let addr1: Ipv4Addr = 0x7f000001.into();
let addr2: Ipv4Addr = [127, 0, 0, 1].into();

println!("{:?}", addr1);    // 127.0.0.1
println!("{:?}", addr2);    // 127.0.0.1

整理

  • Into<T> というトレイトを実装した型は intoT に変換できる
  • From<T> というトレイトを実装した型は fromT から生成できる

参考

https://doc.rust-jp.rs/rust-by-example-ja/conversion/from_into.html