7章9節。
独自のベクタを実装しながら、ライフタイムについて学ぶ構成。
所有権の移動とライフタイムの絡みは面倒だなぁ。
コンパイラくんが色々検出するためなんだろうけど、ライフタイム指定子を使いこなせる気がしない。
とにかく書いてコンパイルエラー量産して慣れるしかないか。
おぼえがき
ライフタイム指定子
&'a self
の'a
- 関数・メソッドの戻り値が参照型の場合、戻り値のライフタイムは以下で推論される
- 引数の中で参照型が1つだけなら、その引数から借用する
- 第1引数が
&self
または&mut self
のメソッドなら、selfから借用する - それ以外の場合はライフタイムを省略できない(コンパイルエラー)
- whare節でライフタイムの長短を明示できる
where 'b: 'a
bはaよりライフタイムが長いと明示
'staticライフタイム
借用経由(&mut self)では、所有権は移動できない
- けど交換はできるという変な理屈
- 交換には
let dest_area = std::mem::replace(&mut src_area, dumy_val);
を使う Option<T>
型には交換のための便利なメソッドが用意されているpub fn take(&mut self) -> Option<T>;
- 所有権を移動し、元の場所にはNoneを返す
pub fn replace(&mut self, value: T) -> Option<T>;
- 所有権を移動し、元の場所にはSome(value)を返す
- 交換には
- けど交換はできるという変な理屈
構造体や列挙型のライフタイム
- 参照型のフィールドをもたせる場合は、定義にライフタイム指定子をつけること
列挙型とnullableポインタ最適化
Option<T>
などの列挙型は、バリアントを識別するためのフィールド「タグ」を持つ- タグのサイズは4byte。例えば
Option<T>
は値4byte+タグ4byte=計8byteが型のサイズ - しかし、下記条件を満たす場合、nullableポインタ最適化の条件を満たせばタグは省略される。
- 2つのバリアントを持つ
- 一方のバリアントはフィールドを持たない
- もう一方のバリアントはフィールドを持つが、そのデータ型にとって全ビット0の状態は不正である
Option<T>型
は、上記条件を満たすため、タグは省略される- 要は、列挙型の値がゼロならフィールドを持ったバリアントだと判断可能ということか
- 必要なスペースは減るけど、実行コストは上がらないの?
- ん、結局バリアントの識別は誰がいつ必要とする話なんだっけ
課題
- P277 ジェネリクスに対するライフタイムの説明はピンときてないので整理が必要
- P280 nullableポインタ最適化の話はそもそもの識別が何のためにあるのか要確認
- トレイトの構文はよく分からん。多分、8章で詳しくやるっぽい
気になったこと
- P280のコラムからの参照されている「図5.6」が見当たらない
- 作者: κeen,河野達也,小松礼人
- 出版社/メーカー: 技術評論社
- 発売日: 2019/05/08
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る