type
による型の別名 (エイリアス) の定義方法について。
以下は代表的な用例。
type Alias = SomeType;
とする事で、型 SomeType
の別名 Alias
を定義できる。
以下では、Vec<f32>
に MyVec
の別名を定義している。
fn main() {
let v = vec![3.0, 2.0];
println!("v = {}", get_vec_str(v));
}
type MyVec = Vec<f32>;
fn get_vec_str(v: MyVec) -> String {
let texts = v.iter().map(f32::to_string);
format!("({})", texts.collect::<Vec<_>>().join(", "))
}
別名には型パラメタを含める事ができる。
以下では、二つの同じ型からなるタプルを Pair<T>
として定義している。
fn main() {
let pair = (40, 20);
println!("pair = {}", get_pair_str(pair));
}
type Pair<T> = (T, T);
fn get_pair_str(p: Pair<i32>) -> String {
format!("({}, {})", p.0, p.1)
}
型パラメタから関連型を導出する型の関数としても利用できる。
以下では、nth1
と nth2
は全く同じ機能になる。
fn main() {
let samples = vec![1, 2, 3];
let item1 = nth1(samples.iter(), 2);
let item2 = nth2(samples.iter(), 2);
assert_eq!(item1, item2);
}
type ToItem<T> = <T as Iterator>::Item;
fn nth1<I: Iterator>(mut iter: I, n: usize) -> Option<I::Item> {
iter.nth(n)
}
fn nth2<I: Iterator>(mut iter: I, n: usize) -> Option<ToItem<I>> {
iter.nth(n)
}
type
エイリアスによる別名は、新しい型として作られるわけではない。そのため、元の型や同じように作られた別名と良くも悪くも互換性がある (取り違えを防ぐ目的では、Newtype パターンが利用可能)。
以下では、f32
に別名 Length
と Time
を定義しているが、それらを取り違えている。
fn main() {
let length = 4000.0;
let time = 3600.0;
println!("speed = {}", speed(time, length));
}
type Length = f32;
type Time = f32;
fn speed(l: Length, t: Time) -> f32 {
l / t
}
type
エイリアスは型の別名を作るだけで、関数の別名までは作らない。そのため、タプルや構造体の別名を作っても、その初期化用関数の別名までは作られない。なお、use Type as Alias;
での別名ではこれができる (ただし、こちらは型パラメタの利用に制限がある)。
以下では、型 Color
の別名 Rgb
を定義しているが、初期化に別名は使えない。
fn main() {
let gray = Color(0x80, 0x80, 0x80);
let blue = Triple(0x00, 0x00, 0xFF);
let aqua = Rgb(0x00, 0xFF, 0xFF);
println!("gray = {}", get_color_str(gray));
println!("blue = {}", get_color_str(blue));
println!("aqua = {}", get_color_str(aqua));
}
struct Color(u8, u8, u8);
use Color as Triple;
type Rgb = Color;
fn get_color_str(color: Color) -> String {
format!("#{:02X?}{:02X?}{:02X?}", color.0, color.1, color.2)
}
error[E0423]: expected function, tuple struct or tuple variant, found type alias `Rgb` --> src\main.rs:4:16 | 4 | let aqua = Rgb(0x00, 0xFF, 0xFF); | ^^^ | = note: can't use a type alias as a constructor
where
は利用不可
、type
エイリアスの型パラメタは where
で制限できない (エラーメッセージの note
を見ると、GitHub へのリンクがあるので将来は変更されるかも…?)。
use std::fmt::Display;
fn main() {
let pair = (40, 20);
println!("pair = {}", get_pair_str(pair));
}
type Pair<T> = (T, T) where T: Display;
fn get_pair_str<T: Display>(p: Pair<T>) -> String {
format!("({}, {})", p.0, p.1)
}
error: where clauses are not allowed after the type for type aliases --> src\main.rs:8:23 | 8 | type Pair<T> = (T, T) where T: Display; | ^^^^^^^^^^^^^^^^ | = note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information