我坚持使用借用和可变的Rust概念:
#[derive(Debug)]
struct Rectangle {
height: u32,
width: u32,
}
fn mut_area(rect_mut: &mut Rectangle) -> u32 {
rect_mut.width /= 2;
rect_mut.height * rect_mut.width
}
fn mut_string(s: &mut String) -> &str {
s.push_str("!");
let len = s.len();
&s[0..len / 2]
}
fn main() {
let mut rect = Rectangle {
height: 50,
width: 40,
};
println!("original rect: {:?}", rect);
let a = mut_area(&mut rect);
println!("area of rect: {}", a);
println!("now rect: {:?}", rect);
let mut s = String::from("helloworld");
println!("original s: {}", s);
let half = mut_string(&mut s);
println!("half of the modified string: {}", half);
println!("modified s: {}", s);
}
当我尝试编译它时,编译器告诉我:
error[E0502]: cannot borrow `s` as immutable because it is also borrowed as mutable
--> <anon>:32:32
|
30 | let half = mut_string(&mut s);
| - mutable borrow occurs here
31 | println!("half of the modified string: {}", half);
32 | println!("modified s: {}", s);
| ^ immutable borrow occurs here
33 | }
| - mutable borrow ends here
我知道有一条关于可变引用的规则:
您只能对特定范围内的特定数据提供一个可变引用。
但为什么可以借用rect
但s
不能?我如何实现我想要的 - 在函数调用后打印修改后的字符串?
答案 0 :(得分:2)
在调用具有a
可变引用的函数后,您可以打印rect
的原因是它返回u32
Copy
能够 - {没有'需要限制rect
的进一步使用,因为在调用mut_area
后不再使用它。
另一方面,mut_string
返回对其参数的引用,因此只要half
在范围内,可变借用仍然有效。这就是为什么你不能为了s
而不可靠地借用println!()
。
为了实现你的目标,我会在s
函数之外改变mut_string
(一个稍微不同的名字现在是一个好主意),所以没有可变的借用 - 它的论证可以不变地借用:
fn mut_string(s: &str) -> &str {
let len = s.len();
&s[0..len / 2]
}
fn main() {
let mut rect = Rectangle {
height: 50,
width: 40,
};
println!("original rect: {:?}", rect);
let a = mut_area(&mut rect); // rect's mutable borrow expires after this assignment
println!("area of rect: {}", a);
println!("now rect: {:?}", rect);
let mut s = String::from("helloworld");
println!("original s: {}", s);
s.push_str("!"); // s is mutated here
let half = mut_string(&s); // s is borrowed immutably
println!("half of the modified string: {}", half);
println!("modified s: {}", s); // another immutable borrow of s
}