今天的Rust之谜来自The Rust Programming Language,第一版的第4.9节.引用和借用的示例有这个例子:
fn main() {
fn sum_vec(v: &Vec<i32>) -> i32 {
return v.iter().fold(0, |a, &b| a + b);
}
fn foo(v1: &Vec<i32>) -> i32 {
sum_vec(v1);
}
let v1 = vec![1, 2, 3];
let answer = foo(&v1);
println!("{}", answer);
}
Run Code Online (Sandbox Code Playgroud)
这看似合理.它打印出"6",这是你所期望如果
v的sum_vec是一个C++参考; 它只是一个内存位置的名称,v1我们定义的向量main().
然后我sum_vec用这个替换了身体:
fn sum_vec(v: &Vec<i32>) -> i32 {
return (*v).iter().fold(0, |a, &b| a + b);
}
Run Code Online (Sandbox Code Playgroud)
它按预期编译和工作.好吧,那不是......完全疯了.编译器试图让我的生活更轻松,我明白了.令人困惑的是,我必须记住这个语言的特定时态,但并不完全是疯狂的.然后我尝试了:
fn sum_vec(v: &Vec<i32>) -> i32 {
return (**v).iter().fold(0, |a, &b| a + b);
}
Run Code Online (Sandbox Code Playgroud)
它仍然有效!我勒个去?
fn sum_vec(v: &Vec<i32>) -> i32 {
return (***v).iter().fold(0, |a, &b| a + b);
}
Run Code Online (Sandbox Code Playgroud)
type [i32] cannot be dereferenced.哦,感谢上帝,这是有道理的.但我原本预计会有两次迭代!
拉斯特引用是不是C++"在内存中的另一个地名,"但什么是他们?它们也不是指针,关于它们的规则似乎要么是深奥的,要么是高度特殊的.发生了什么,这样一个引用,一个指针和一个指向指针的指针在这里同样运作良好?
规则不是临时的,也不是真正的深奥.检查其类型v和各种解除引用:
fn sum_vec(v: &Vec<i32>) {
let () = v;
}
Run Code Online (Sandbox Code Playgroud)
你会得到:
v - > &std::vec::Vec<i32>*v - > std::vec::Vec<i32>**v - > [i32]您已经理解的第一个解引用.第二个取消引用是由于这个Deref特点.Vec<T>对...的推论[T].
执行方法查找时,有一组直接的规则:
Rust中的引用不是C++"内存中另一个地方的名称".
它们绝对是记忆中一个地方的名字.实际上,它们编译成你知道的相同的C/C++指针.