目次

Rustの勉強[Dropトレイト その1]

(更新: )ぎじゅつ

はじめに

#

NO IMAGEThe Rust Programming Language 日本語版 - The Rust Programming Language 日本語版
を読んでいる

  • 今日の勉強会の発表でBox<T>はポインタであることがわかった
  • 参照外しは型が違うということも理解できた

お勉強

#

NO IMAGEDropトレイトで片付け時にコードを走らせる - The Rust Programming Language 日本語版

  • ここをやる

メモ

#

Dropトレイトで片付け時にコードを走らせる

#
  • とりあえずざっくり読む
  • 光ってそうなところを書いていく

Dropトレイトの機能は、ほぼ常にスマートポインタを実装する時に使われるからです。
std::mem::dropで早期に値をドロップする

  • Dropトレイトはスマートポインタにほぼ使われていてドロップするが何かわかればいいということがわかった

どんな型に対してもDropトレイトの実装を提供することができ、指定したコードは、 ファイルやネットワーク接続などのリソースを解放するのに活用できます。

  • おお、リソースからメモリ開放するやつか
    • 完な気がするな
  • もう少しみる

Rustでは、 値がスコープを抜ける度に特定のコードが走るよう指定でき、コンパイラはこのコードを自動的に挿入します。

  • はぇ~

    • ということはRustのライフタイムはこいつによって実現されている?
  • 実装を見るとわかりやすそうなのでみる

struct CustomSmartPointer {
    data: String,
}

impl Drop for CustomSmartPointer {
    fn drop(&mut self) {
        // CustomSmartPointerをデータ`{}`とともにドロップするよ
        println!("Dropping CustomSmartPointer with data `{}`!", self.data);
    }
}

fn main() {
    let c = CustomSmartPointer {
        data: String::from("my stuff"),
    }; // 俺のもの
    let d = CustomSmartPointer {
        data: String::from("other stuff"),
    }; // 別のもの
    println!("CustomSmartPointers created."); // CustomSmartPointerが生成された
}
  • CustomSmartPointerを2つ作っているな
  • ああこれは単純にどのタイミングでこのトレイトが呼ばれるのか見ているのか
CustomSmartPointers created.
Dropping CustomSmartPointer with data $(other stuff)!
Dropping CustomSmartPointer with data $(my stuff)!
  • ふむ、最後のprintln!が終わったら2つとも実行されているな
  • 想定とおり

通常は、メッセージ出力ではなく、 自分の型が走らせる必要のあるクリーンアップコードを指定するでしょう。

  • ここめっちゃわかりやすかったな

Rustは、 Dropトレイトのdropメソッドを手動で呼ばせてくれません
スコープが終わる前に値を強制的にドロップさせたいなら、 代わりに標準ライブラリが提供するstd::mem::drop関数を呼ばなければなりません。

  • これもそのままの意味だな
fn main() {
    let c = CustomSmartPointer {
        data: String::from("some data"),
    };
    println!("CustomSmartPointer created.");
    c.drop();
    // mainの終端の前にCustomSmartPointerがドロップされた
    println!("CustomSmartPointer dropped before the end of main.");
}
error[E0040]: explicit use of destructor method
(エラー: デストラクタメソッドを明示的に使用しています)
  --> src/main.rs:14:7
   |
14 |     c.drop();
   |       ^^^^ explicit destructor calls not allowed
  • ああ、これは内部になるdropが呼べないって話しね

エラーメッセージはデストラクタという専門用語を使っていて、これは、 インスタンスを片付ける関数の一般的なプログラミング専門用語です。

  • 知らなかった
fn main() {
    let c = CustomSmartPointer {
        data: String::from("some data"),
    };
    println!("CustomSmartPointer created.");
    drop(c);
    // CustomSmartPointerはmainが終わる前にドロップされた
    println!("CustomSmartPointer dropped before the end of main.");
}
CustomSmartPointer created.
Dropping CustomSmartPointer with data $(some data)!
CustomSmartPointer dropped before the end of main.
  • 想定どおり
  • DBのコネクションとかこれでやるんだろうか

まとめ

#
  • メモリの開放というのは以前からよくやった記憶があるのでスッと入ってきた
  • 前回のスマートポインタもポインタなのでそれらすべてを開放するというのでかなり解像度が上がった
  • あとは短ったのであえて時間があってじっくり読んでみた
    • 結構よかった

次はここ
NO IMAGERc<T>は、参照カウント方式のスマートポインタ - The Rust Programming Language 日本語版