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的方法搜索时,最多只会做一次自动引用,然后就一直做自动解引用。当为一个变量x找搜索方法f时,具体算法如下:
1、当前x上是否有方法f,有调用之;
2、没有,则在x上自动引用一次变成&x,&x上如果有方法f,则调用之;
3、没有,则尝试*x,一直重复3步,直到找到或失败。
时间: 2024-11-10 13:45:48