[英]Shadowing in Rust and Fighting the Borrow Checker
每次我接受用户输入时,我都会创建一个新变量(通过阴影)来获取输入。 我认为这是低效的,而不是阴影的目的,我还能如何有效地重用变量输入?
如果没有阴影,它会导致错误cannot borrow "input" as mutable because it is also borrowed as immutable
。 据我了解,获取用户输入需要一个可变引用。
use std::io; // Import for IO
fn main() {
let name: &str; // Variables
let balance: f32; // Variables
let interest: f32; // Variables
let mut input = String::new(); // Variables
println!("Please enter your name: "); // Print
io::stdin().read_line(&mut input).expect("failed to read from stdin");
name = input.trim();
println!("Please enter your bank account balance: "); // Print
loop {
let mut input = String::new(); // Remove this and I get an error
io::stdin().read_line(&mut input).expect("failed to read from stdin");
match input.trim().parse::<f32>() {
Ok(_) => {
balance = input.trim().parse().unwrap();
break;
},
Err(_) => println!("Your balance cannot contain letters or symbols"),};
}
}
println!("Please enter your interest rate percent: "); // Print
loop {
let mut input = String::new(); // Remove this and I get an error
io::stdin().read_line(&mut input).expect("failed to read from stdin");
match input.trim().parse::<f32>() {
Ok(_) => {
interest = input.trim().parse().unwrap();
break;
},
Err(_) => println!("Your balance cannot contain letters or symbols"),};
}
}
println!("{}, your gain from interest is : ${}", name, (interest * balance * 0.01)); // Print
}
来自 Java,我对借用的工作方式以及何时隐藏是一个好主意感到困惑。 我知道旧值仍然存在,并且任何对它的引用都意味着如果您不再需要旧值,那么您将无缘无故地占用资源。 任何建议都有帮助,谢谢。
该错误告诉您问题:
error[E0502]: cannot borrow `input` as mutable because it is also borrowed as immutable
--> src/main.rs:20:27
|
13 | name = input.trim();
| ----- immutable borrow occurs here
...
20 | io::stdin().read_line(&mut input).expect("failed to read from stdin");
| ^^^^^^^^^^ mutable borrow occurs here
...
47 | println!("{}, your gain from interest is : ${}", name, (interest * balance * 0.01)); //Print
| ---- immutable borrow later used here
input.trim()
创建一个对 input 的不可变引用并将其存储在name
。 如果删除String::new()
调用,那么您正在调用io::stdin().read_line(&mut input)
,它接受对输入的可变引用,但在name
变量中仍然存在对输入的不可变引用。
在 Rust 中,不允许不可变引用和可变引用同时存在,因此编译器会报错。
你不能真正在这里重用变量,你需要克隆或做你正在做的事情并完全创建一个新的字符串。
HexCoder 的回答解释了您不能在input
重用String
,因为它是由name
借用的。 但是,为了使其可重用,您需要做的就是将input.trim()
复制到一个带有自己的缓冲区的新String
:
let name: String = input.trim().into();
由于name
不再借用input
,您可以擦除input
并重新使用其缓冲区。 要擦除字符串,请使用String::clear
:
input.clear(); // instead of `input = String::new();`
这是一个更完整的示例,其中我还使用模式绑定来避免对input
两次解析,并将balance
和interest
的声明移至可以立即初始化的位置。
变量阴影有一些微妙之处,尤其是当您考虑编译器优化时; 这些问题也可能有用:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.