fn main() {
let mut name = String::from("Charlie");
let x = &mut name;
let y = x; // x has been moved
say_hello(y);
say_hello(y); // but y has not been moved, it is still usable
change_string(y);
change_string(y);
}
fn say_hello(s: &str) {
println!("Hello {}", s);
}
fn change_string(s: &mut String) {
s.push_str(" Brown");
}
Run Code Online (Sandbox Code Playgroud)
当我分配x
到y
x
已被移动。但是,当我在函数中使用它时,我希望可以移动具有移动语义的东西。但是,我仍然可以在后续调用后使用参考。也许这与 say_hello() 接受不可变引用有关,但 change_string() 接受可变引用但引用仍未移动。
我的印象是可变引用(即&mut T
)总是被移动.这是完全合理的,因为它们允许独占的可变访问.在下面的代码中,我为另一个可变引用分配了一个可变引用,并移动了原始引用.结果我不能再使用原件了:
let mut value = 900;
let r_original = &mut value;
let r_new = r_original;
*r_original; // error: use of moved value *r_original
Run Code Online (Sandbox Code Playgroud)
如果我有这样的功能:
fn make_move(_: &mut i32) {
}
Run Code Online (Sandbox Code Playgroud)
并修改我的原始示例,如下所示:
let mut value = 900;
let r_original = &mut value;
make_move(r_original);
*r_original; // no complain
Run Code Online (Sandbox Code Playgroud)
我期望r_original
在make_move
用它调用函数时移动可变引用.然而,这不会发生.我仍然可以在通话后使用参考.
如果我使用通用函数make_move_gen
:
fn make_move_gen<T>(_: T) {
}
Run Code Online (Sandbox Code Playgroud)
并称之为:
let mut value = 900;
let r_original = &mut value;
make_move_gen(r_original);
*r_original; // error: use of moved …
Run Code Online (Sandbox Code Playgroud) fn say_hello(s: &str) {
println!("Hello {}", s);
}
Run Code Online (Sandbox Code Playgroud)
为什么这样做
fn main() {
let mut name = String::from("Charlie");
let x = &mut name;
say_hello(x);
name.push_str(" Brown");
}
Run Code Online (Sandbox Code Playgroud)
但这不是吗?
fn main() {
let mut name = String::from("Charlie");
let x = &mut name;
name.push_str(" Brown");
say_hello(x);
}
Run Code Online (Sandbox Code Playgroud)
我所做的只是切换两个函数的顺序,但似乎x
在这两种情况下都可变地借用了 name,而 push_str 也可变地借用了 name,那么为什么第一个示例编译?
如果我取消调用,say_hello()
即使仍然有两个可变借用,为什么两者的顺序无关紧要?
编辑:这相似吗?
fn change_string(s: &mut String) { // s is mutably borrowed but isn't used yet
println!("{}", s.is_empty()); // so the scopes don't overlap even though is_empty …
Run Code Online (Sandbox Code Playgroud) 我正在努力理解 Rust 的所有权和借用模型,但对以下内容感到困惑:
let mut x: i32 = 1;
let ref_x = &mut x;
let refref_x = &mut *ref_x;
*refref_x = 2;
*ref_x = 3;
Run Code Online (Sandbox Code Playgroud)
据我所知,我实际上正在创建两个单独的可变引用x
。为什么这段代码在避免通过指针间接寻址并仅将第 3 行更改为
let refref_x = &mut x;
Run Code Online (Sandbox Code Playgroud)
显然不是?我是否误解了中心概念,或者编译器是否在后台添加了一些魔法?