auto deref or auto ref ?
trait Double {
fn double(self) -> usize;
}
impl<'a> Double for &'a String {
fn double(self) -> usize { self.len()}
}
impl<'a, 'b, 'c> Double for &'a &'b &'c String {
fn double(self) -> usize { self.len() * 2 }
}
pub fn main() {
let x = "hello".to_string(); println!("x:String => {}", x.double());
let x = &x; println!("x:&String => {}", x.double());
let x = &x; println!("x:&&String => {}", x.double());
let x = &x; println!("x:&&&String => {}", x.double());
let x = &x; println!("x:&&&&String => {}", x.double());
}
OUTPUT:
x:String => 5
x:&String => 5
x:&&String => 10
x:&&&String => 10
x:&&&&String => 10
how the compiler decide the ord of auto-deref or auto-ref?
if we remove &&&String version of impl:
trait Double {
fn double(self) -> usize;
}
impl<'a> Double for &'a String {
fn double(self) -> usize { self.len()}
}
pub fn main() {
let x = "hello".to_string(); println!("x:String => {}", x.double());
let x = &x; println!("x:&String => {}", x.double());
let x = &x; println!("x:&&String => {}", x.double());
let x = &x; println!("x:&&&String => {}", x.double());
let x = &x; println!("x:&&&&String => {}", x.double());
}
OUTPUT:
x:String => 5
x:&String => 5
x:&&String => 5
x:&&&String => 5
x:&&&&String => 5
if we remove the &String version of impl:
trait Double {
fn double(self) -> usize;
}
impl<'a, 'b, 'c> Double for &'a &'b &'c String {
fn double(self) -> usize { self.len() * 2 }
}
pub fn main() {
let x = "hello".to_string(); println!("x:String => {}", x.double()); // error
let x = &x; println!("x:&String => {}", x.double()); // error
let x = &x; println!("x:&&String => {}", x.double());
let x = &x; println!("x:&&&String => {}", x.double());
let x = &x; println!("x:&&&&String => {}", x.double());
}
まとめ:xのメソッド検索では、最大1回の自動参照のみが作成され、自動解参照が実行されます.1つの変数xに対して探索方法fを探す場合、具体的なアルゴリズムは以下の通りである.
1、現在のxに方法fがあるかどうか、呼び出されているかどうか.
2、ない場合は、x上で自動的に&xを参照し、&x上に方法fがあれば呼び出す.
3、ない場合は*xを試し、見つけたり失敗したりするまで3ステップ繰り返します.