我刚刚开始学习一点Rust,并且对变量的可变性概念非常感兴趣。
我试图写一些与这个C ++程序非常相似的东西。
#include <cstdio>
void do_something(int &var) {
var++;
}
int main() {
int a = 3;
int b = a;
printf("a is %d and b is %d\n", a, b);
do_something(b);
printf("a is %d and b is %d\n", a, b);
return 0;
}
我希望看到:
a是3,b是3
a是3,b是4
这个想法是传递引用呈现b
可变,但a
不可变。
以下是我假设在Rust中编写此程序的方法:
fn main() {
let a: i32 = 3;
let b: &mut i32 = &a;
println!("a is {} and b is {}", a, b);
do_something(b);
println!("a is {} and b is {}", a, b);
}
fn do_something(var: &mut i32) {
(*var)+=1;
}
但是,由于可变性不匹配,我收到错误。
错误:类型不匹配:
预期
&mut i32
, 找到&i32
(值的可变性不同)[E0308]
有没有方法可以在没有::New
的Rust中保护这种传递引用样式?我的猜测是我可以使用.clone()
,但我不是肯定的。
答案 0 :(得分:7)
你误解了代码的作用。这是实际等效代码:
fn main() {
let a: i32 = 3;
let mut b = a;
println!("a is {} and b is {}", a, b);
do_something(&mut b);
println!("a is {} and b is {}", a, b);
}
fn do_something(var: &mut i32) {
*var += 1;
}
在您的C代码中, b
不是任何形式的引用;它与a
完全没有联系。只是C允许你传递一个值并让它推断它必须引用它,而Rust对这些事情非常明确,所以你需要写&mut b
而不仅仅是{{1将可变引用传递给b
。之前的do_something
只会使mut b
槽变为可变,允许您改变其中的值(没有它,您将无法创建对b
的可变引用)。