Trait
Rust の型に共通の振る舞いを定義するインターフェース機構
Rust型システム
Trait とは
Trait は Rust の型に共通の振る舞い (メソッド) を定義するインターフェース機構である。TypeScript の interface、Java の interface、Haskell の型クラスに相当する。Rust には継承がなく、Trait でポリモーフィズムを実現する。
基本的な使い方
// Trait の定義
trait Summary {
fn summarize(&self) -> String;
// デフォルト実装 (オーバーライド可能)
fn preview(&self) -> String {
format!("{}...", &self.summarize()[..50])
}
}
// Trait の実装
struct Article { title: String, content: String }
impl Summary for Article {
fn summarize(&self) -> String {
format!("{}: {}", self.title, &self.content[..100])
}
}
struct Tweet { username: String, text: String }
impl Summary for Tweet {
fn summarize(&self) -> String {
format!("@{}: {}", self.username, self.text)
}
}
Trait 境界 (ジェネリクスの制約)
// T は Summary trait を実装している型のみ受け付ける
fn notify(item: &impl Summary) {
println!("Breaking: {}", item.summarize());
}
// where 句で複数の Trait 境界
fn process<T>(item: &T) -> String
where
T: Summary + Display + Clone,
{
format!("{}: {}", item, item.summarize())
}
TypeScript の interface との比較
| 観点 | Rust Trait | TypeScript interface |
|---|---|---|
| デフォルト実装 | あり | なし (abstract class で代替) |
| 孤児ルール | 外部の型に外部の Trait を実装不可 | 制限なし |
| 静的ディスパッチ | impl Trait (ゼロコスト) |
- |
| 動的ディスパッチ | dyn Trait (vtable) |
常に動的 |
| 関連型 | あり (type Output) |
なし |
標準ライブラリの重要な Trait
| Trait | 用途 | 例 |
|---|---|---|
Display |
人間向けの文字列表現 | println!("{}", value) |
Debug |
デバッグ用の文字列表現 | println!("{:?}", value) |
Clone |
値の複製 | value.clone() |
Iterator |
イテレーション | for item in collection |
From / Into |
型変換 | String::from("hello") |
Serialize / Deserialize |
JSON 変換 (serde) | serde_json::to_string(&value) |
derive マクロ
#[derive(Debug, Clone, Serialize, Deserialize)]
struct User {
id: String,
name: String,
email: String,
}
// Debug, Clone, Serialize, Deserialize が自動実装される
Lambda での活用
use serde::{Deserialize, Serialize};
#[derive(Deserialize)]
struct Request { user_id: String }
#[derive(Serialize)]
struct Response { message: String }
// Serialize/Deserialize trait で JSON の変換が自動化
理論と実装の両面から学ぶなら関連書籍が参考になる。