Ghost 新行和空格在 Rust 中自动添加到 String
Ghost new line and spaces added to String automatically in Rust
我在循环开始前使用 String::new()
创建了一个空的可变字符串变量。然后我一进入循环就打印字符串值,通过用户输入将同一变量的类型更改为整数 u32,在修剪所有空格后,\n、\r 等。
在循环的下一次迭代中,变量的值返回到 String 并且即将更改其类型,但是当我通过打印检查 String 的值时,它有一些幽灵 \n 和空格或一些从之前的整数值继承而来的幽灵字符。
如果整数是 3 位,例如 534 它有 5 个字符
如果整数是 1 位,例如 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 :
这是什么原因造成的?
有没有办法在每次迭代开始时维护循环之前的值?
或者可以同时维护上一次迭代的 Integer 值和 u32 类型?
我 运行 在尝试使用 rust 文档中的“The Book”学习 rust 时遇到了这个问题,具体来说是在我试图弄乱第 2 章中的代码时(猜一个数字)项目)。
对于变量在 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
仅 returns 一个字符串切片,不修改基础 String
值。
那么 guess
将在第一次迭代后的循环语句开头包含尾随换行符是有道理的。
Is there a way to maintain the value before the loop, at the start of every iteration? or may be maintain the value of Integer from previous iteration and u32 Type at the same time?
将最后一个问题改写为“一种维护上一次迭代的整数值的方法”,然后可以通过给它一个新名称并将其向上移动来实现.在下面的示例中,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);
}
另请参阅:
- How to ignore the line break while printing a string read from stdin?
- The Rust Programming Language, 3.1 Variables and Mutability
我在循环开始前使用 String::new()
创建了一个空的可变字符串变量。然后我一进入循环就打印字符串值,通过用户输入将同一变量的类型更改为整数 u32,在修剪所有空格后,\n、\r 等。
在循环的下一次迭代中,变量的值返回到 String 并且即将更改其类型,但是当我通过打印检查 String 的值时,它有一些幽灵 \n 和空格或一些从之前的整数值继承而来的幽灵字符。
如果整数是 3 位,例如 534 它有 5 个字符
如果整数是 1 位,例如 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 :
这是什么原因造成的?
有没有办法在每次迭代开始时维护循环之前的值?
或者可以同时维护上一次迭代的 Integer 值和 u32 类型?
我 运行 在尝试使用 rust 文档中的“The Book”学习 rust 时遇到了这个问题,具体来说是在我试图弄乱第 2 章中的代码时(猜一个数字)项目)。
对于变量在 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
仅 returns 一个字符串切片,不修改基础String
值。
那么 guess
将在第一次迭代后的循环语句开头包含尾随换行符是有道理的。
Is there a way to maintain the value before the loop, at the start of every iteration? or may be maintain the value of Integer from previous iteration and u32 Type at the same time?
将最后一个问题改写为“一种维护上一次迭代的整数值的方法”,然后可以通过给它一个新名称并将其向上移动来实现.在下面的示例中,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);
}
另请参阅:
- How to ignore the line break while printing a string read from stdin?
- The Rust Programming Language, 3.1 Variables and Mutability