はじめに
NO IMAGEThe Rust Programming Language 日本語版 - The Rust Programming Language 日本語版
を読んでいる
- むちゃくちゃ眠い
- 継続のためにとりあえずやる
- そろそろトレイトを終わらせたい
前回の振り返り
- なにやったんだ。。。?
- 戻り値は明示的に型指定する必要があったのでジェネリクスが避けられることもあった
- それがimplで戻り値も返せて嬉しい
今日読む場所
お勉強
- ここをやる
- トレイト境界を使用して、条件分けする
メモ
ジェネリックな型引数を持つimplブロックにトレイト境界を与えることで、 特定のトレイトを実装する型に対するメソッド実装を条件分けできます。例えば、 リスト10-16の型Pair
は、常にnew関数を実装します。しかし、Pair は、 内部の型Tが比較を可能にするPartialOrdトレイトと出力を可能にするDisplayトレイトを実装している時のみ、 cmp_displayメソッドを実装します。
- うーーーん??
- なんか良くない実装に見えるのでできるよぐらいにしておきたいな
また、別のトレイトを実装するあらゆる型に対するトレイト実装を条件分けすることもできます。 トレイト境界を満たすあらゆる型にトレイトを実装することは、ブランケット実装(blanket implementation)と呼ばれ、 Rustの標準ライブラリで広く使用されています。
- 辛いな、意味わからんのに標準ライブラリにあるのか
トレイトとトレイト境界により、ジェネリックな型引数を使用して重複を減らしつつ、コンパイラに対して、 そのジェネリックな型に特定の振る舞いが欲しいことを指定するコードを書くことができます。 それからコンパイラは、トレイト境界の情報を活用してコードに使用された具体的な型が正しい振る舞いを提供しているか確認できます。 動的型付き言語では、その型に定義されていないメソッドを呼び出せば、実行時 (runtime) にエラーが出るでしょう。 しかし、Rustはこの種のエラーをコンパイル時に移したので、コードが動かせるようになる以前に問題を修正することを強制されるのです。
- どこまでも仕組みで解決しようとする精神が偉い
- ブランケット実装が意味不明すぎてムカついた
- geminiに助けてもらった
トレイト境界を満たすあらゆる型にトレイトを実装する
- geminiに助けてもらった
- これが全てだった
impl<T: Display> ToString for T {
// --snip--
}
- まずこれでDisplayをimplしていないと受けとれない型になる
- 私はここでToStringメソッドを持っているかをチェックしていると思っていた
- 違っていて、ここのDisplayは + を使えば条件を増やせる
- 増やした条件が当っていた場合に自動的にToStringのトレイトをimplできる
- それをすることでdefaultで実装されていればtoStringメソッドが実装されてなくてもimplされて使えるようになる
すでに使っている他のジェネリクスに、ライフタイムと呼ばれるものがあります。 ライフタイムは、型が欲しい振る舞いを保持していることではなく、必要な間だけ参照が有効であることを保証します。 ライフタイムがどうやってそれを行うかを見てみましょう。
- 次はライフタイムらしい
まとめ
- トレイト境界(treit bound)でジェネリクスに対して条件を決めて型安全を守る
- ブランケット実装を行うことにより、トレイト境界の条件をクリアしたものに別のトレイトを自動でimplできる
- これをするとゲームの条件アイテム見たいなかんじで勝手に使えるメソッドが増える
- ということは条件を見たせばメソッドが増えるのと同意義
- 次はライフタイムを読む