String::new()
我在回圈開始之前使用創建了一個空的可變字串變數。然后我一進入回圈就列印字串值,通過用戶輸入將同一變數的型別更改為整數 u32,在修剪所有空格、\n、\r 等之后。
在回圈的下一次迭代中,變數的值又回到了 String 并且即將改變它的型別,但是當我通過列印它來檢查 String 的值時,它有一些幽靈 \n 和空格或繼承了一些幽靈字符從前一個整數值。
如果整數是 3 位,例如 534,
如果整數是 1 位,它有 5 個字符,例如 3,
如果我給空值作為輸入,它有 3 個字符,決議失敗它仍然是字串,但仍然在下一次迭代中字串有 2 個字符。
我創建了一個函式來跟蹤變數的型別。
use std::io;
//function to return type of a variable
fn type_of<T>(_: &T) -> String {
return format!("{}", std::any::type_name::<T>());
}
fn main() {
let mut guess = String::new();
loop {
println!(
"At start of loop : {},{}",
type_of(&guess),
guess.chars().count()
);
println!("value : {}", guess);
//emptying string
String::clear(&mut guess);
println!(
"after clearing : {},{}",
type_of(&guess),
guess.chars().count()
);
//getting input for string
println!("Enter value :");
io::stdin()
.read_line(&mut guess)
.expect("Failed to read line");
//converted its values to interger u32 after trimming spaces,\n and \r and stuffs like that
let guess: u32 = match guess.trim().parse() {
Ok(a) => a,
Err(b) => {
println!("{}", b);
println!("after reciving error : {}", type_of(&guess));
continue;
}
};
println!("after type conversion : {}", type_of(&guess));
println!("value: {}", guess);
}
}
輸出是:
At start of loop : alloc::string::String,0
value :
after clearing : alloc::string::String,0
Enter value :
111
after type conversion : u32
value: 111
At start of loop : alloc::string::String,5
value : 111
after clearing : alloc::string::String,0
Enter value :
1
after type conversion : u32
value: 1
At start of loop : alloc::string::String,3
value : 1
after clearing : alloc::string::String,0
Enter value :
cannot parse integer from empty string
after reciving error : alloc::string::String
At start of loop : alloc::string::String,2
value :
after clearing : alloc::string::String,0
Enter value :
這是什么原因造成的?
有沒有辦法在每次迭代開始時保持回圈之前的值?或者可能同時保持上一次迭代的整數值和 u32 型別?
當我嘗試使用 rust docs 中的“The Book”學習 rust 時遇到了這個問題,特別是當我試圖弄亂第 2 章(猜數字專案)中的代碼時。
uj5u.com熱心網友回復:
對于變數在 Rust 中的作業方式存在誤解。可以存在具有相同名稱的不同變數,這個程序稱為shadowing。在這個程式中,我們有兩個名為 的變數guess
。
前面代碼的以下簡化顯示了這種模式。
let guess: mut = String::new(); // <-- guess #1, lives outside loop
loop {
guess.clear();
println!("Enter value :");
io::stdin()
.read_line(&mut guess)
.expect("Failed to read line");
// guess #2, lives inside loop
// vvvvv
let guess: u32 = match guess.trim().parse() {
Ok(a) => a,
Err(b) => {
eprintln!("{}", b);
continue;
}
};
println!("value: {}", guess);
}
第一個總是型別String
,第二個總是型別u32
。變數永遠不能改變型別。改變的是在什么范圍內可以看到和使用哪個。由于第二個guess
僅在回圈中間宣告,因此guess
在該宣告之前提及將意味著第一個猜測,即字串。
結合以下兩個事實:
read_line
讀取換行符并將其包含到輸出字串中;trim
只回傳一個字串切片,而不修改底層String
值。
guess
那么在第一次迭代后回圈陳述句的開頭將包含尾隨換行符是有意義的。
有沒有辦法在每次迭代開始時保持回圈之前的值?或者可能同時保持上一次迭代的整數值和 u32 型別?
將最后一個問題改寫為“一種從上一次迭代中保持整數值的方法”,那么可以通過給它一個新名稱并將其向上移動來實作。在下面的示例中,guess_num
在每次迭代時重新分配,而不是每次都宣告。
let guess: mut = String::new();
let mut guess_num: u32 = 0;
loop {
println!("Previous number (or 0 if first iteration): {}", guess_num);
guess.clear();
println!("Enter value :");
io::stdin()
.read_line(&mut guess)
.expect("Failed to read line");
guess_num = match guess.trim().parse() {
Ok(a) => a,
Err(b) => {
eprintln!("{}", b);
continue;
}
};
println!("value: {}", guess);
}
也可以看看:
- 當我可以擁有可變變數系結時,為什么我需要重新系結/陰影?
- 列印從標準輸入讀取的字串時如何忽略換行符?
- Rust 編程語言,3.1 變數和可變性
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/430670.html
上一篇:列印給定字串的某些字母的函式