トレイトとは?
CoddyのRustジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 29/61。
ジェネリックを使うと、あらゆる型で動作するコードを書けますが、場合によっては、ある型が特定のことをできることを保証する必要があります。そこでtraitの出番です。
trait は、型が実装しなければならない一連の method を定義します。これを契約だと考えてください。この契約に「署名」する型は、指定された動作を提供することを約束します。他の言語でインターフェースを使ったことがあるなら、trait は似たような目的を果たします。
trait を Define する方法は次のとおりです。
trait Describable {
fn describe(&self) -> String;
}
traitキーワードはtraitを導入し、その後にその名前が続きます。中かっこの内側では、メソッドのシグネチャ、つまり名前、パラメーター、戻り値の型だけを宣言し、本体は記述しません。シグネチャの後のセミコロンは、これが実装ではなく要件であることを示します。
この Describable trait は次のように述べています。「私を実装する任意の型は、自身への参照を受け取り、String を返す describe method を提供しなければならない。」この trait は、method がどのように動作するかには関知しません。それは、それを実装する各型に委ねられています。
複数の異なる型が同じ trait を実装すると、trait は強力になります。Book、Car、PersonはすべてDescribableにすることができ、それぞれが独自の説明を提供します。trait は、それらすべてがこの共通の機能を共有することを保証します。
チャレンジ
簡単最初の trait を定義しましょう!trait は契約、つまり、それを実装するあらゆる型が特定の振る舞いを提供するという約束を定めます。異なる型が自分自身の概要を提供するために実装できる Summarizable trait を作成します。
コードを2つのファイルに整理します。
summary.rs:Summarizableという名前の public trait を Define し、単一の method signaturesummarize(&self) -> Stringを持たせます。Remember、trait の definition では semicolon を付けた method signature のみを declare します。body はありません。これは Rust に対して「この trait を実装するあらゆる型は、Stringを返すsummarizemethod を提供しなければならない」と伝えます。main.rs: summary module を取り込み、trait が定義されたことを確認する message を print します。まだ trait の実装方法を学んでいないため(それは次のレッスンです!)、trait が正しくコンパイルされることだけを確認します。
main file で、trait の definition が有効であることを確認するため、次の message を print します。
Summarizable trait defined successfully!この challenge では、trait definition の syntax、つまり trait keyword、trait name、そして implementation なしで method signature を declare することだけに焦点を当てます。次のレッスンでは、struct にこの trait を implement させる方法を学びます!
自分で試してみよう
mod summary;
fn main() {
// TODO: トレイトが定義されたことの確認メッセージを出力する
// Expected output: "Summarizable trait defined successfully!"
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Rustオンラインコンパイラ