英文:
Does &mut T implements Borrow<T> break a mutable reference rule?
问题
&mut T
实现了 Borrow<T>
,所以 (&mut T).borrow()
会创建 &T
。这是否违反了“如果我们有一个可变引用,就不能有任何其他引用(可变或不可变)”的规则?
use std::borrow::Borrow;
let mut n = 1;
let r1: &mut i32 = &mut n;
let r2: &i32 = r1.borrow();
println!("log: {r1} {r2}");
这段代码可以编译,但如果我将 r1.borrow()
改为 &n
,它将报错。
引用系统的确切规则是什么?
英文:
&mut T
implements Borrow<T>
,so (&mut T).borrow()
will create &T
. Does this break the rule that “if we have one mutable reference, we can not have any other references (mutable or not)”?
use std::borrow::Borrow;
let mut n = 1;
let r1: &mut i32 = &mut n;
let r2: &i32 = r1.borrow();
println!("log: {r1} {r2}");
The code compiles, but if I change r1.borrow()
to &n
, it will report error
What's the exact rule of the reference system?
答案1
得分: 1
以下是代码部分的翻译:
let r1: &mut i32 = &mut n;
let r2: &i32 = &*r1;
let r3: &i32 = &*r1;
fn takes_ref_mut_ref(_: &&mut i32) {}
takes_ref_mut_ref(&r1);
let r4 = *r1;
fn print_three(a: &i32, b: &i32, c: &i32) {
println!("{a} {b} {c}")
}
print_three(r1, r2, r3);
fn takes_ref_ref(_: &&i32) {}
takes_ref_ref(&r1);
fn print_three_mut(a: &mut i32, b: &i32, c: &i32) {
println!("{a} {b} {c}")
}
print_three_mut(r1, r2, r3);
*r1 = 5;
英文:
This is more general than Borrow
. You can do the same thing with regular references:
let r1: &mut i32 = &mut n;
let r2: &i32 = &*r1;
When you think about it, it's very necessary to be able to make immutable references from mutable references. For example, you need it to call &self
methods on &mut
variables.
But rust still ensures you aren't using the mut
property of the variable.
Things you can do:
- Give out more
&
references
let r3: &i32 = &*r1;
- Use it behind another
&
reference
fn takes_ref_mut_ref(_: &&mut i32) {}
takes_ref_mut_ref(&r1);
- Copy types that implement
Copy
let r4 = *r1;
- Deref to
&
(this does&*r1
implicitly)
fn print_three(a: &i32, b: &i32, c: &i32) {
println!("{a} {b} {c}")
}
print_three(r1, r2, r3);
Things you can't do:
- Implicitly use it as a
&&
fn takes_ref_ref(_: &&i32) {}
takes_ref_ref(&r1);
- Use it as
&mut
directly
fn print_three_mut(a: &mut i32, b: &i32, c: &i32) {
println!("{a} {b} {c}")
}
print_three_mut(r1, r2, r3);
- And obviously, mutate the variable
*r1 = 5;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论