スポンサーリンク
Rustには継承はないがポリモーフィズムはある。C++やJavaのようなオブジェクト指向ではポリモーフィズムの実現のために継承があるようなイメージがあるので、この関係が奇妙に見える。
継承とは「鷹も燕も"鳥"の特性をすべて持ち、その他に若干の差異がある同種のモノである」という考え方をする。だからどうしても子クラスが肥大化していく。そのあたりを嫌った結果らしい。
// 振る舞い trait Flying{ fn fly(&self); }
// 構造体 鷹 struct Hawk{ weight:f32, speed:f32, } // トレイトのR実装 impl Flying for Hawk{ // メソッド fn fly(&self){ println!("鷹が飛ぶ {} km/h \n",self.speed ); } }
// 構造体 ハチドリ struct Hummingbird{ weight:f32, speed:f32, } // トレイトのR実装 impl Flying for Hummingbird{ // メソッド fn fly(&self){ println!("ハチドリが飛ぶ {} km/h\n", self.speed); } }
fn main() { // スタック上に確保する固定長配列は [T;N]の形をしている // T ... Type , N ... 個数 let ary:[ Box<dyn Flying> ; 2 ] = [ // Boxはヒープにメモリを確保する。 Box::new(Hawk{weight:1100.0,speed:190.0}), // アカオノスリ Box::new(Hummingbird{weight:20.0,speed:98.0}) // ハチドリ ]; ary[0].fly(); ary[1].fly(); }
C++の継承が「Birdの特性を持った鷹を実装」という形であるのに対し、
Rustのtraitは「Flyという振る舞いを、鷹や燕の特性に付与する」というような発想をすると、現時点ではとらえている(下図、現時点の解釈)
C++のオブジェクト指向だと飛べないはずのペンギンもflyを持たざるを得ないが、Rustのtraitであればペンギンにはflyを付与しなければよいだけの話だということになる。