ubnt-intrepid's blog

書いてあることがブログの内容です

Rust でメソッドのオーバーロード

Rust でメソッドのオーバーロードをしたい場合,オーバロード対象のメソッドを持つ Trait を用意し,各型ごとに実装を記述する.

mod hoge {
  pub struct Hoge;

  // 引数の型を引数
  pub trait Foo<T> {
    fn foo(&self, foo: T);
  }

  // 引数の型ごとに実装を記述
  impl Foo<i32> for Hoge {
    fn foo(&self, foo: i32) { println!("i32"); }
  }
  impl Foo<f64> for Hoge {
    fn foo(&self, foo: f64) { println!("f64"); }
  }
}

fn main() {
  use hoge::{Hoge, Foo};

  let hoge = Hoge;
  
  hoge.foo(1i32);   // => "i32"
  hoge.foo(1f64);   // => "f64"
}

上の方法だと,呼び出し側で 毎回 Foo をインポートする必要がある. それを避けたいのであれば(?),例えば次のようにすれば回避できる.

mod hoge {
  pub struct Hoge;

  impl Hoge {
    pub fn foo<T:Foo>(&self, foo: T) { T::foo(self, foo) }
  }

  pub trait Foo {
    fn foo(hoge: &Hoge, foo: Self);
  }

  impl Foo for i32 {
    fn foo(hoge: &Hoge, foo: i32) { println!("i32"); }
  }

  impl Foo for f64 {
    fn foo(hoge: &Hoge, foo: f64) { println!("f64"); }
  }
}

fn main() {
  let hoge = hoge::Hoge;

  hoge.foo(1i32);
  hoge.foo(1f64);
}

まぁ正直何がうれしいのかよくわからないけど...