Drop トレイト
Drop を実装している値では、スコープから外れるときに実行するコードを指定できます。
struct Droppable {
name: &'static str,
}
impl Drop for Droppable {
fn drop(&mut self) {
println!("Dropping {}", self.name);
}
}
fn main() {
let a = Droppable { name: "a" };
{
let b = Droppable { name: "b" };
{
let c = Droppable { name: "c" };
let d = Droppable { name: "d" };
println!("Exiting block B");
}
println!("Exiting block A");
}
drop(a);
println!("Exiting main");
}
This slide should take about 8 minutes.
std::mem::dropはstd::ops::Drop::dropと同じではありません。- スコープ外になると、値は自動的にドロップされます。
- 値がドロップされる際、
std::ops::Dropを実装している場合は、そのDrop::drop実装が呼び出されます。 - その後、
Dropを実装しているかどうかにかかわらず、すべてのフィールドもドロップされます。 std::mem::dropは、任意の値を受け取る空の関数にすぎません。重要なのは、この関数が値の所有権を取得することで、スコープの最後で値がドロップされることです。これは、スコープ外になる前に値を明示的にドロップするための便利な方法です。- この方法は、
dropで何らかの処理(ロックの解放、ファイルのクローズなど)を行うオブジェクトに使用すると便利です。
- この方法は、
議論のポイント:
Drop::dropがselfをパラメータとして取らないのはなぜですか?- 短い回答: その場合、ブロックの最後に
std::mem::dropが呼び出されるため、別のDrop::dropが呼び出され、スタック オーバーフローが発生します。
- 短い回答: その場合、ブロックの最後に
drop(a)をa.drop()に置き換えてみてください。