自動参照外し (Auto-dereferencing)
元ネタ
https://sodocumentation.net/rust/topic/2574/auto-dereferencing
The dot operator ドット演算子
.演算子によって、コンパイル時に必要なだけの*が挿入され、自動で参照外しが行われる。
Deref型強制の一種。
let mut name: String = "Hello World".to_string();
// derefされない
name.push('!');
let name_ref = &name; // len()メソッドは、参照型の&Stringには実装されていないが、自動参照外し(Auto deref)によって呼び出しが解決される let name_len = name_ref.len(); // 本来は参照元のメソッドを呼び出すには、参照外しが必要となる let name_len2 = (*name_ref).lne();
値のラッピングに対するDerefの実装
ラッピングした値を返すDerefトレイトを実装することで、 コンパイル時に型変換することができる。
use std::ops::Deref;
use std::fmt::Debug;
// Optionをラッパー
#[derive(Debug)]
struct RichOption<T>(Option<T>);
// 参照外しされた際、ラッパーしたOptionを返す
impl<T> Deref for RichOption<T> {
type Target = Option<T>;
fn deref(&self) -> &Option<T> {
&self.0
}
}
impl<T: Debug> RichOption<T> {
fn print_inner(&self) {
println!("{:?}", self.0)
}
}
fn main() {
let x = RichOption(Some(1));
// Optionのメソッドが呼び出せる
println!("{:?}",x.map(|x| x + 1));
// 参照外しによってOptionに変換できる
fn_that_takes_option(&x);
// RichOptionに実装されたメソッドも呼び出せる
x.print_inner()
}
fn fn_that_takes_option<T : std::fmt::Debug>(x: &Option<T>) {
println!("{:?}", x)
}
関連
アンチパターン Deref ポリモフィズム - あるマのメモ書き
Appendix
B - Operators and Symbols - The Rust Programming Language
| 演算子 | 例 | 説明 |
|---|---|---|
* |
*expr |
Dereference |
& |
&expr, &mut expr |
Borrow |