[英]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.