トレイト - 共通の振る舞いを定義する

https://doc.rust-lang.org/book/ch10-02-traits.html

トレイト: 共通の振る舞いの定義

概要

  • トレイトを使って共通の振る舞いを定義
  • トレイトのデフォルト実装
  • トレイトをパラメーターに指定できる impl Trait
  • トレイト境界 impl Traitシンタックスシュガー
  • 複数のトレイト境界を指定できる + Sntax
  • 明快なwhere節を使ったトレイト境界
  • トレイト実装型を返す impl Trait
    • 異なる型をダイナミックに選択して返すことはできない
  • トレイト境界を使ってlargest関数を修正
  • トレイト境界を使って条件的にメソッドを実装する

トレイトを使って共通の振る舞いを定義

トレイトの定義

共通の振る舞いをトレイトとして抽出する。

トレイトの実装

共通の振る舞いを持つ型にたいしてトレイトを実装する。

トレイトのデフォルト実装

トレイトをパラメーターに指定できる impl Trait

トレイト境界 impl Traitシンタックスシュガー

複数のトレイト境界を指定できる + Sntax

明快なwhere節を使ったトレイト境界

トレイト実装型を返す impl Trait

* 異なる型をダイナミックに選択して返すことはできない

トレイト境界を使ってlargest関数を修正

ジェネリック型パラメーターを使った関数

// Listing 10-5: A definition of the largest function that uses 「generic type parameters」 but doesn’t compile yet
fn largest<T>(list: &[T]) -> T {
    let mut larget = list[0];
    for &item in list {
        // error[E0369]: binary operation `>` cannot be applied to type `&T`
        if item > largest {  
            largest = item;
        }
    }
    largest
}

&T型はバイナリオペレーターを適用することができないというエラーが表示される。

>オペレーターは、std::cmp::PartialOrdトレイトで定義されているため、Tに対してPartialOrdトレイト境界を指定すれば良い。

fn larget<T: PartialOrd>(list: &[T]) -> &T {

しかしスライス(配列も)型、共有参照型から所有権を移動することができない。

$ cargo run
   Compiling chapter10 v0.1.0 (file:///projects/chapter10)
error[E0508]: cannot move out of type `[T]`, a non-copy slice
 --> src/main.rs:2:23
  |     // スライスから所有権を移動させることはできない
2 |     let mut largest = list[0];
  |                       ^^^^^^^
  |                       |
  |                       cannot move out of here
  |                       move occurs because `list[_]` has type `T`, which does not implement the `Copy` trait
  |                       help: consider borrowing here: `&list[0]`

   Compiling chapter10 v0.1.0 (file:///projects/chapter10)
error[E0507]: cannot move out of a shared reference
 --> src/main.rs:4:18
  |     // パターンマッチにより所有権が移動させようとしている
4 |     for &item in list {
  |         -----    ^^^^
  |         ||
  |         |data moved here
  |         |move occurs because `item` has type `T`, which does not implement the `Copy` trait
  |         help: consider removing the `&`: `item`

Copyトレイトをつけることによって解消することができる。(ただしCopyトレイトを実装していない型では使えなくなる) その場合は、Cloneトレイトをつけることができる。

fn largest<T: PartialOrd + Copy>(list: &[T] -> &T {

トレイト境界を使って条件的にメソッドを実装する

関連

Advanced Traits - The Rust Programming Language

Object Oriented Programming Features of Rust - The Rust Programming Language