トレイトとは?
CoddyのRustジャーニー「Object Oriented Programming」セクションの一部 — レッスン 29/61。
ジェネリクスを使用すると、任意の型で動作するコードを記述できますが、型が特定のことを実行できることを保証する必要がある場合があります。ここでトレイトの出番です。
トレイトは、型が実装しなければならないメソッドのセットを定義します。これを契約と考えてください。この契約に「署名」する型は、指定された動作を提供することを約束します。他の言語でインターフェースを使用したことがある場合、トレイトは同様の目的を果たします。
トレイトは次のように定義します:
trait Describable {
fn describe(&self) -> String;
}
trait キーワードはトレイトを導入し、その後にその名前が続きます。波括弧の中では、メソッドのシグネチャ(名前、パラメータ、戻り値の型のみで、本体はなし)を宣言します。シグネチャの後のセミコロンは、これが実装ではなく要件であることを示しています。
この Describable トレイトは次のように述べています。「私を実装するすべての型は、自身への参照を受け取り String を返す describe メソッドを提供しなければならない」。このトレイトは、メソッドがどのように動作するかについては関知しません。それは実装する各型に委ねられています。
トレイトは、複数の異なる型が同じトレイトを実装するときに強力になります。Book、Car、そして Person はすべて Describable になることができ、それぞれが独自の記述を提供します。トレイトは、それらすべてがこの共通の機能を共有することを保証します。
チャレンジ
簡単最初のトレイトを定義しましょう!トレイトは契約を確立します。つまり、それを実装する型が特定の振る舞いを提供することを約束するものです。ここでは、さまざまな型が自分自身の要約を提供するために実装できる Summarizable トレイトを作成します。
コードを2つのファイルに分けて構成します:
summary.rs:Summarizableという名前の公開トレイトを定義し、summarize(&self) -> Stringという単一のメソッドシグネチャを持たせます。トレイトの定義では、メソッドのシグネチャをセミコロンで宣言するだけで、本体(body)は記述しないことを忘れないでください。これはRustに対して、「このトレイトを実装するすべての型は、Stringを返すsummarizeメソッドを提供しなければならない」と伝えます。main.rs: summaryモジュールを取り込み、トレイトが定義されたことを確認するメッセージを出力します。トレイトの実装方法はまだ学習していないため(それは次のレッスンです!)、ここではトレイトが正しくコンパイルされることを確認するだけです。
メインファイルで、トレイトの定義が有効であることを確認するために、次のメッセージを出力してください:
Summarizable trait defined successfully!このチャレンジでは、トレイト定義の構文(trait キーワード、トレイト名、および実装を持たないメソッドシグネチャの宣言)に純粋に焦点を当てています。次のレッスンでは、構造体にこのトレイトを実装させる方法を学びます!
チートシート
トレイトは、型が実装しなければならない一連のメソッドを定義します。これは、型が特定の振る舞いを提供することを保証する契約として機能します。
トレイトを定義するには、traitキーワードの後にトレイト名とメソッドのシグネチャを記述します:
trait Describable {
fn describe(&self) -> String;
}
トレイト内のメソッドのシグネチャには、名前、パラメータ、戻り値の型が含まれますが、本体はありません。セミコロンは、これが実装する型に対する要件であることを示しています。
複数の異なる型が同じトレイトを実装でき、それぞれが要求されたメソッドの独自の実装を提供します。
自分で試してみよう
mod summary;
fn main() {
// TODO: トレイトが定義されたことを示す確認メッセージを出力する
// 期待される出力: "Summarizable trait defined successfully!"
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。