トレイト まとめ
Self
将来実装される型を表す。
pub trait FromStr { type Err; fn from_str(s: &str) -> Result<Self, Self::Err>;
impl FromStr for
Haskellで言うところの型変数 a
class Eq a where
Eq
: 型クラスa
: 型変数, 具体型である必要がある。(型コンストラクタはNG)
関連型 type
実装側で定義できる型を表す
put trait Iterator { type Item; fn next(&mut self) -> Option<Self::Item>;
ジェネリクスパラメーター
トレイトはジェネリクスを持てる。
pub trait From<T> { fn from(T) -> Self; }
デフォルトジェネリックス型
pub trait Add<Rhs=Self> { type Output; fn add(self, rhs: Rhs) -> Self::Output; }
use std::ops::Add; #[derive(Debug)] struct Point { x: i32, y: i32, } // ジェネリックスパラメーターを指定しなくてよい impl Add for Point { type Output = Point; // 推測されない fn add(self, other: Point) -> Point { Point { x: self.x + other.x, y: self.y + other.y, } } } let p1 = Point { x: 1, y: 2 }; let p2 = Point { x: 3, y: 4 }; let p3 = p1 + p2; println!("{:?}", p3);
デフォルトのジェネリックス型と異なる型の場合は指定する
use std::ops::Add; struct Millimeters(u32); struct Meters(u32); impl Add<Meters> for Millimeters { type Output = Millimeters; fn add(self, other: Meters) -> Millimeters { Millimeters(self.0 + (other.0 * 1000)) } }
トレイト境界も可能
pub trait AsRef<T> where T: ?Sized, { fn as_ref(&self) -> &T; }
サブトレイト
トレイトの継承。
pub trait Copy: Clone { }
Haskellでいうところのサブクラス
class Eq a => Ord a where
トレイトオブジェクト dyn
トレイトは型宣言に使うことはできない
// warning: trait objects without an explicit `dyn` are deprecated fn open(path: AsRef<std::path::Path>) { std::fs::File::open(path).unwrap(); }
'&dyn'をつける。&
を付ける理由はトレイトオブジェクトはサイズ未決定型であるため。
fn open(path: &dyn AsRef<std::path::Path>) {