LoginSignup
13
5

More than 3 years have passed since last update.

RustのトレイトとDeriveのキホンがよくわからんかったので自分なりに落とし込んだ

Posted at

https://doc.rust-jp.rs/the-rust-programming-language-ja/1.6/book/traits.html
https://doc.rust-jp.rs/rust-by-example-ja/trait/derive.html

このドキュメントを見てもよくわからなかったので自分なりにキホンがわかるように。

まずざっくりと

トレイトとは

トレイトはある型が提供しなければならない機能をRustのコンパイラに伝える言語機能です。
メソッド構文で関数を呼び出すのに用いていた、 impl キーワードを思い出して下さい。

継承(Derive)とは

コンパイラには、[#derive]アトリビュートを用いることで型に対して特定のトレイトの標準的な実装を提供する機能があります。より複雑なことを行わせたい場合には、同名のトレイトを手動で実装することも可能です。

なにがなんだか...

まずトレイトからみてみる

struct Circle {
    x: f64,
    y: f64,
    radius: f64,
}

impl Circle {
    fn area(&self) -> f64 {
        std::f64::consts::PI * (self.radius * self.radius)
    }
}

このプログラムをトレイトを用いて作り直すと,

struct Circle {
    x: f64,
    y: f64,
    radius: f64,
}

trait HasArea {
    fn area(&self) -> f64;
}

impl HasArea for Circle {
    fn area(&self) -> f64 {
        std::f64::consts::PI * (self.radius * self.radius)
    }
}

こうなるのかな?
HasAreaトレイトをCircle構造体が実装したらなにかいいことがあるのでしょうか。

もう一度トレイトのドキュメントを見てみます。

fn print_area<T>(shape: T) {
    println!("This shape has an area of {}", shape.area());
}

このプログラムはエラーを吐くみたいです。
なるほどTはどんな型にもなれるから,.area()が使える保証がない(安全性がない)ためだとドキュメントが言っています。

fn print_area<T: HasArea>(shape: T) {
    println!("This shape has an area of {}", shape.area());
}

こういうふうにしてHasAreaトレイトを実装しているあらゆる型Tという書き方にしてやれば実行できるようです。
なるほど使いみちがわかってきました。
Deriveではこのトレイトを構造体に追加できるみたいな感じなんですかね?

Deriveについて

Deriveを使うとどうやら特定のトレイトの標準的な,みんなが使うような実装をカンタンに行うことができるようです。
なるほど,標準的な実装があるのならさっきのトレイトのドキュメントみたいに改めて実装しなくてもいいみたいですね。

このDeriveが使える特定のトレイトは,
- Eq
- PartialEq
- Ord
- PartialOrd
- Clone
- Hash
- Default
- Debug
というふうに決められてるみたいですね〜!
※ドキュメントに載っているZeroはDeprecatedになっているみたいです...

https://www.reddit.com/r/rust/comments/2o3s5v/why_were_stdnum_zero_and_one_traits_deprecated/

おわり

ざっくりとトレイトderiveの雰囲気を掴むことができたので,実際に手を動かして行こうと思います。

13
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
5