トレイト まとめ

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>) {