今天的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);
}
这似乎很合理。它打印&#34; 6&#34;,这是你期望的
v
的{{1}}是C ++参考;它只是一个记忆的名字
location,我们在sum_vec
中定义的向量v1
。
然后我将main()
的主体替换为:
sum_vec
它按预期编译和工作。好吧,那不是......完全疯了。编译器试图让我的生活更轻松,我明白了。令人困惑的是,我必须记住这些语言的特定时态,但并非完全疯狂。然后我试了一下:
fn sum_vec(v: &Vec<i32>) -> i32 {
return (*v).iter().fold(0, |a, &b| a + b);
}
它仍然有效!怎么了?
fn sum_vec(v: &Vec<i32>) -> i32 {
return (**v).iter().fold(0, |a, &b| a + b);
}
fn sum_vec(v: &Vec<i32>) -> i32 {
return (***v).iter().fold(0, |a, &b| a + b);
}
。哦,感谢上帝,这是有道理的。但我原本预计会有两次迭代!
Rust中的引用不是C ++&#34;内存中另一个地方的名称,&#34;但 是什么?它们也不是指针,关于它们的规则似乎是深奥的或高度特殊的。发生了什么,这样一个引用,一个指针和一个指向指针的指针在这里同样运作良好?
答案 0 :(得分:9)
规则不是 ad-hoc ,也不是真正的深奥。检查v
的类型及其各种解除引用:
fn sum_vec(v: &Vec<i32>) {
let () = v;
}
你会得到:
v
- &gt; &std::vec::Vec<i32>
*v
- &gt; std::vec::Vec<i32>
**v
- &gt; [i32]
您已经了解的第一个解引用。第二个取消引用归功于Deref
特征。 Vec<T>
[T]
var string = <p>It's a round about way.</p> <p><!-- pagebreak -->But Maybe this is the way?</p>;
的解除引用。
执行方法查找时,there's a straight-forward set of rules:
Rust中的引用不是C ++“内存中另一个地方的名称”,
它们绝对是记忆中某个地方的名字。实际上,它们会编译成你知道的相同的C / C ++指针。