use std::ops::Deref;
impl<T> Deref for MyBox<T> {
typeTarget = T; // ※第19章で詳説fnderef(&self) -> &T {
&self.0
}
}
// let var = MyBox::new(12);// println!("var: {}", *var); // deref()によって参照外しができる!
関数やメソッドで暗黙的な参照外し型強制
参照外し型強制:Derefを実装する型への参照を,元の型への参照に変換する機能
下記の例では,&MyBox<String>を&Stringに変換している
fnhello(name: &str) {
println!("Hello, {}!", name);
}
fnmain() {
let m = MyBox::new(String::from("Rust"));
hello(&m);
}
暗黙的な参照外し型強制が無いと
*m:MyBox<String>をStringに参照外ししている
(*m)[..]:文字列全体と等しい文字列スライスをとる
fnmain() {
let m = MyBox::new(String::from("Rust"));
hello(&(*m)[..]);
}
参照外し型強制が可変性と相互作用する方法
コンパイラは下記のルールに則り参照外し型強制を行う
T: Deref<Target=U>->&Tを&Uに
T: DerefMut<Target=U>->&mut Tを&mut Uに
T: Deref<Target=U>->&mut Tを&Uに
15.3 Dropトレイトで片付け時にコードを走らせる
Dropトレイトは,値がスコープを抜けるときに起こることをカスタマイズできる
Box<T>はDropをカスタマイズして,ヒープ領域のメモリを解放する
ファイルやネットワーク接続などのリソースを解放するのに活用できる
本節では下記の内容を取り扱う
Dropの使い方
明示的にDropを起動させる
Dropトレイトの使い方
変数を生成した順序と逆の順序でドロップされる
structCustomSmartPointer {
data: String,
}
implDropfor CustomSmartPointer {
fndrop(&mutself) {
// CustomSmartPointerをデータ`{}`とともにドロップするよprintln!("Dropping CustomSmartPointer with data `{}`!", self.data);
}
}
fnmain() {
let c = CustomSmartPointer { data: String::from("my stuff") }; // 俺のものlet d = CustomSmartPointer { data: String::from("other stuff") }; // 別のものprintln!("CustomSmartPointers created."); // CustomSmartPointerが生成された
}
$ cargo run
CustomSmartPointers created.
Dropping CustomSmartPointer with data `other stuff`!
Dropping CustomSmartPointer with data `my stuff`!
std::mem::dropで早期に値をドロップする
Dropトレイトのdrop()を手動で呼ぶことができない
代わりにstd::mem::drop()で強制的にドロップさせる
fnmain() {
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.