このページでは Rust で頻出する変換処理を理解するために Into<T>
と From<T>
についてまとめる。
Into<T>
Into<T>
というトレイトを実装した型は into
で T
に変換できる。
convert/mod.rs
trait Into<T>: Sized {
fn into(self) -> T;
}
たとえば &str
も String
も Into<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>
というトレイトを実装した型は from
で T
から生成できる。
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>
があれば自動でコンパイラに実装してもらえる。
実際に Ipv4Addr
は into
でも生成できる。
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>
というトレイトを実装した型はinto
でT
に変換できる -
From<T>
というトレイトを実装した型はfrom
でT
から生成できる
参考