[英]Mutable and Immutable reference inside println
I am fairly new to Rust and encountered some beginner problems and want to share my solution with others around the internet that I haven't found in existing threads.我对 Rust 还很陌生,遇到了一些初学者问题,想与互联网上的其他人分享我在现有线程中找不到的解决方案。 I wonder if there is a more Rust approach to it.
我想知道是否有更多的Rust方法。
I want to print out the height, width and area of a Rectangle.我想打印出矩形的高度、宽度和面积。
struct Rectangle {
height: u32,
width: u32,
area: u32,
}
impl Rectangle{
fn area(& mut self) -> u32 {
self.area = self.height * self.width;
return self.area
}
}
fn main() {
let mut rect1 = Rectangle {height: 20, width: 30, area: 0};
println!("Rectangle has height {} width {} and area {}", rect1.height, rect1.width, rect1.area());
}
which gives me the error cannot borrow as immutable because it is also borrowed as mutable这给了我错误不能借用为不可变的,因为它也被借用为可变的
error[E0502]: cannot borrow `rect1` as mutable because it is also borrowed as immutable
--> src/main.rs:17:88
|
17 | println!("Rectangle has height {} width {} and area {}", rect1.height, rect1.width, rect1.area());
| -----------------------------------------------------------------------------------^^^^^^^^^^^^--
| | | |
| | | mutable borrow occurs here
| | immutable borrow occurs here
| immutable borrow later used here
My solution我的解决方案
println!("Rectangle has height {1} width {2} and area {0}", rect1.area(), rect1.height, rect1.width);
changing the order in the println!
更改
println!
statement.陈述。
I know that you cannot have an immutable and mutable reference at the same time, because the immutable reference does not expect the values to be changed.我知道您不能同时拥有不可变和可变引用,因为不可变引用不期望值被更改。 See here .
见这里。 But why does my solution work?
但为什么我的解决方案有效? Clearly, there still is a mutable and immutable reference in the same
println!
显然,在同一个
println!
statement but with changed order.声明但更改了顺序。
But why does my solution work?
但为什么我的解决方案有效? Clearly, there still is a mutable and immutable reference in the same println.
显然,在同一个 println 中仍然存在一个可变和不可变的引用。 statement but with changed order.
声明但更改了顺序。
Nope!没有! The thing is
area()
requires a mutable borrow but does not keep one , since it returns an owned value ( u32
) rather than a borrowed one ( &u32
), so the borrow only lasts for the extent of the call and is released once the call returns.问题是
area()
需要一个可变借用但不保留一个,因为它返回一个拥有的值( u32
)而不是一个借用的值( &u32
),所以借用只在调用范围内持续,一旦调用返回。
Now you could expect the same of height
and width
, the trap is that println!
现在你可以期待
height
和width
相同,陷阱就是println!
implicitly borrows its parameters, so when you println,("{}". rect.height)
it compiles to something along the lines of Arguments("", &rect.height)
, creating a borrow until the end of the formatting process.隐式借用其参数,因此当您
println,("{}". rect.height)
时,它会编译为Arguments("", &rect.height)
行中的内容,创建一个借用直到格式化过程结束。
Now because the borrow is implicit you can't deref' the attribute ( *rec.height
) as that would be &*rec.height
where rec.height
is still a u8, however there is an other method which isblock expressions :现在,因为借用是隐式的,所以您不能取消引用属性 (
*rec.height
),因为这将是&*rec.height
,其中rec.height
仍然是 u8,但是还有另一种方法是块表达式:
Blocks are always value expressions and evaluate the last expression in value expression context.
块始终是值表达式,并评估值表达式上下文中的最后一个表达式。 This can be used to force moving a value if really needed.
如果确实需要,这可用于强制移动值。
This means that &{rec.height}
will first copy (or move) the value out of the structure, then borrow that copy.这意味着
&{rec.height}
将首先将值复制(或移动)出结构,然后借用该副本。 Therefore you can also fix the call by writing:因此,您还可以通过以下方式修复呼叫:
println!("Rectangle has height {} width {} and area {}", {rect1.height}, {rect1.width}, rect1.area());
That will copy the two attributes out first, then println!
这将首先复制这两个属性,然后
println!
will implicitly borrow them, but it won't need to borrow the structure itself leading to three non-overlapping borrows.将隐式借用它们,但不需要借用结构本身导致三个不重叠的借用。
In that case, you may want to add a comment to explain why you're doing that as it's... odd.在这种情况下,您可能需要添加评论来解释您为什么这样做,因为它......很奇怪。
Then again, I think your area
is an anti-pattern, so YMMV.再说一次,我认为您的
area
是反模式,所以 YMMV。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.