我正在学习/试验Rust,在我用这种语言找到的所有优雅中,有一个让我感到困惑并且看起来完全不合适的特点.
在进行方法调用时,Rust会自动取消引用指针.我做了一些测试来确定确切的行为:
struct X { val: i32 }
impl std::ops::Deref for X {
type Target = i32;
fn deref(&self) -> &i32 { &self.val }
}
trait M { fn m(self); }
impl M for i32 { fn m(self) { println!("i32::m()"); } }
impl M for X { fn m(self) { println!("X::m()"); } }
impl M for &X { fn m(self) { println!("&X::m()"); } }
impl M for &&X { fn m(self) { println!("&&X::m()"); } }
impl M for &&&X { …Run Code Online (Sandbox Code Playgroud) 经过一些讨论,我现在有点困惑之间的关系auto-dereferencing和deref coercion.
似乎 "自动解除引用"一词仅适用于取消引用的目标是方法接收者,而"deref强制"一词似乎适用于函数参数及其所需的所有上下文.
我认为解除引用并不总是涉及deref强制,但我不确定:dereferencing是否始终使用某些Deref::deref特征实现?
如果是这样,是T: Deref<Target = U> where T: &U编译器内置的实现者吗?
最后,在编译器隐式转换&&&&x为的所有情况下,使用术语"autoderef"听起来很自然&x:
pub fn foo(_v: &str) -> bool {
false
}
let x="hello world";
foo(&&&&x);
Run Code Online (Sandbox Code Playgroud)
这是社区的普遍共识吗?
为什么这段代码会编译?
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
fn main() {
let x = "eee";
let &m;
{
let y = "tttt";
m = longest(&x, &y);
}
println!("ahahah: {}", m);
}
Run Code Online (Sandbox Code Playgroud)
对我来说,由于生命周期,应该存在编译错误。如果我用 编写相同的代码i64,则会出现错误。
fn ooo<'a>(x: &'a i64, y: &'a i64) -> &'a i64 {
if x > y {
x
} else {
y
}
}
fn main() {
let x = …Run Code Online (Sandbox Code Playgroud)