デフォルトメソッド
トレイトのデフォルト実装
「デフォルトメソッド」はCoddyKit上の無料Learn Rust Codingレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLearn Rust Coding学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Learn Rust Codingコースには全4レッスンが含まれています。
本体を持つメソッド
トレイトメソッドはシグネチャだけである必要はありません。トレイトはデフォルト実装、つまり実装者が自動的に取得するメソッド本体を提供できます。
これにより、多くの型にまたがる定型コードを減らせます。
デフォルトメソッド
本体はトレイトの中に直接記述します。トレイトを実装する型は、追加のコードなしで無料でそれを継承します。
trait Greet {
fn hello(&self) -> String {
String::from("Hello there")
}
}
struct Robot;
impl Greet for Robot {}
fn main() {
println!("{}", Robot.hello());
}デフォルトのオーバーライド
どの実装者も独自のバージョンを提供してデフォルトをオーバーライドできます。その型では、オーバーライドした実装がデフォルトに置き換わります。
trait Greet {
fn hello(&self) -> String { String::from("Hello there") }
}
struct Robot;
struct Pirate;
impl Greet for Robot {}
impl Greet for Pirate {
fn hello(&self) -> String { String::from("Arr!") }
}
fn main() {
println!("{}", Robot.hello());
println!("{}", Pirate.hello());
}必須メソッドを呼び出すデフォルト
デフォルトメソッドは、同じトレイトの他のメソッドを呼び出せます。デフォルト実装のないメソッドでも可能です。これは強力なパターンです。実装者は小さな中核部分を提供し、デフォルトがその上に豊かな振る舞いを構築できます。
trait Summary {
fn title(&self) -> String;
fn preview(&self) -> String {
format!("Read more about: {}", self.title())
}
}
struct Article { headline: String }
impl Summary for Article {
fn title(&self) -> String { self.headline.clone() }
}
fn main() {
let a = Article { headline: String::from("Rust Rocks") };
println!("{}", a.preview());
}テンプレートメソッドパターン
この必須メソッドとデフォルトメソッドの組み合わせがテンプレートメソッドパターンです。トレイトはデフォルト実装で全体の流れを定義し、変化する部分を必須メソッドとして残します。
trait Report {
fn body(&self) -> String;
fn render(&self) -> String {
format!("=== REPORT ===\n{}\n==============", self.body())
}
}
struct Sales;
impl Report for Sales {
fn body(&self) -> String { String::from("Sales up 10%") }
}
fn main() {
println!("{}", Sales.render());
}複数のデフォルト
トレイトでは、必須メソッドとデフォルトメソッドを自由に組み合わせられます。実装者が提供する必要があるのは必須メソッドだけです。
trait Animal {
fn name(&self) -> String;
fn legs(&self) -> u32 { 4 }
fn describe(&self) -> String {
format!("{} has {} legs", self.name(), self.legs())
}
}
struct Dog;
impl Animal for Dog {
fn name(&self) -> String { String::from("Dog") }
}
fn main() {
println!("{}", Dog.describe());
}デフォルトと標準トレイト
多くの標準トレイトはデフォルトに依存しています。たとえばIteratorで必須なのはnextだけで、すべてのアダプターとコンシューマーはそれを基盤とするデフォルトメソッドです。
そのため、1つのメソッドでツールボックス全体を利用できるようになります。
性能のためのオーバーライド
デフォルト実装で動作しても、特化したバージョンのほうが高速な場合があります。実装者はそのメソッドだけをオーバーライドし、残りのデフォルトはそのまま使えます。
trait Counter {
fn items(&self) -> Vec<i32>;
fn total(&self) -> i32 {
self.items().iter().sum()
}
}
struct Fast { precomputed: i32 }
impl Counter for Fast {
fn items(&self) -> Vec<i32> { vec![] }
fn total(&self) -> i32 { self.precomputed }
}
fn main() {
println!("{}", Fast { precomputed: 99 }.total());
}使いやすいトレイトを保つ
良いトレイト設計では、必須にするメソッドを少数にし、残りには便利なデフォルトを提供します。実装者の作業は最小限で済み、豊富なインターフェースを利用できます。
注意点
デフォルトメソッドが使えるのは、他のトレイトメソッドと、それらを通じたselfの背後の型だけです。未知の実装者のフィールドに直接アクセスすることはできません。デフォルトはトレイト自身のメソッドを中心に設計しましょう。
デフォルトと必須の違い
本体を持つトレイトメソッドはデフォルトで、シグネチャだけを持つものは必須です。実装者はすべての必須メソッドを提供する必要がありますが、デフォルトは変更せずに残せます。
trait Logger {
fn line(&self) -> String;
fn log(&self) {
println!("LOG: {}", self.line());
}
}
struct App;
impl Logger for App {
fn line(&self) -> String { String::from("started") }
}
fn main() {
App.log();
}クイックチェック
デフォルトメソッドについての理解度を確認しましょう。
まとめ
トレイトのデフォルト実装について学びました。
- トレイトメソッドには、デフォルト実装として本体を含められる
- 実装者はそれを無料で継承でき、オーバーライドもできる
- デフォルトは必須メソッドを呼び出せるため、テンプレートメソッドパターンを実現できる
- 必須メソッドを少数にして、使いやすいトレイトを保てる
よくある質問
「デフォルトメソッド」レッスンは無料ですか?
はい。「デフォルトメソッド」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Learn Rust Codingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Learn Rust Codingコースには全4レッスンが含まれています。
「デフォルトメソッド」で何を学びますか?
トレイトのデフォルト実装 ブラウザで直接実行するハンズオンコードでLearn Rust Codingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Learn Rust Codingを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのLearn Rust Codingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「デフォルトメソッド」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このLearn Rust Codingレッスンでコードを書いて実行できますか?
はい。すべてのLearn Rust Codingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。