[英]Rust Borrow Semantics String
I have a block of code 我有一段代码
let mut current_room = None;
for (ref room_id, ref poker_room) in &self.planning_pokers {
if poker_room.has_player(user_id.clone()) {
current_room = Some(room_id.clone());
break
}
}
match current_room {
Some(room_id) => {
self.planning_pokers.get_mut(&room_id.clone()).unwrap().remove_player(user_id.clone());
if self.planning_pokers.is_empty() {
self.planning_pokers.remove(&room_id.clone());
}
},
None => (),
_ => ()
}
println!("Player {} joined room {}", join_room.room_id.clone(), user_id.clone());
if self.planning_pokers.contains_key(&join_room.room_id.clone()) {
}
This fails to compile due to a mutable and immutable borrow conflict. 由于可变和不可变的借用冲突,因此无法编译。 The conflict in question pertains to me setting the value of current_room
to Some(room_id.clone())
. 有问题的冲突与我将current_room
的值设置为Some(room_id.clone())
。 If I instead do Some(room_id.clone().to_string())
everything works as expected. 如果我改为执行Some(room_id.clone().to_string())
一切正常。 Why is this the case? 为什么会这样呢? And why does the rust compiler give me an error that is seemingly unrelated? 为何rust编译器给我一个看似无关的错误?
For reference this is the error: 供参考,这是错误:
cannot borrow
self.planning_pokers
as mutable because it is also borrowed as immutable 不能将self.planning_pokers
借为可变的,因为它也被借为不可变的
It looks like room_id
is a double reference of type &&T
. 看起来room_id
是&&T
类型的双重引用。 This means that in Some(room_id.clone())
, you are cloning a borrowed reference to data that self.planning_pokers
owns, rather than cloning the underlying data itself. 这意味着在Some(room_id.clone())
,您正在克隆对self.planning_pokers
拥有的数据的借用引用 ,而不是克隆基础数据本身。 Because you then assign it to the variable current_room
in the outer scope, self.planning_pokers
remains borrowed throughout. 因为您然后将其分配给外部作用域中的变量current_room
,所以self.planning_pokers
始终保持借用状态。 It might help to see that in this case, current_room
is of type Option<&T>
. 在这种情况下, current_room
的类型为Option<&T>
可能会有所帮助。
Some(room_id.to_string())
instead creates a copy of the underlying data which is moved into current_room
. Some(room_id.to_string())
会创建基础数据的副本,该副本将被移到current_room
。 In this case current_room
is of type Option<T>
. 在这种情况下, current_room
的类型为Option<T>
。
The difference is (I believe) due to Rust's auto-dereferencing behaviour . (我相信)差异是由于Rust的自动引用行为 。 Immutable references implement Clone
, and so Rust calls the method on &T
. 不可变的引用实现Clone
,因此Rust调用&T
上的方法。 However, they do not implement ToString
, so Rust dereferences all the way down to T
. 但是,它们没有实现ToString
,因此Rust一直取消对T
引用。
Note: rust-clippy warns about this very issue. 注意: rust-clippy会就此问题发出警告。 From the wiki : 从维基 :
What it does: Checks for usage of .clone() on an &&T. 它的作用:检查&& T上.clone()的使用。
Why is this bad? 为什么这样不好? Cloning an &&T copies the inner &T, instead of cloning the underlying T. 克隆&& T会复制内部的&T,而不是克隆基础T。
Example: 例:
fn main() {
let x = vec![1];
let y = &&x;
let z = y.clone();
println!("{:p} {:p}",*y, z); // prints out the same pointer
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.