使用以下代码,我尝试返回用户输入的温度和温度,但是徒劳无功。然后,我试图返回f32,但仍然很难......
Q1。我在底部得到错误的原因是因为'let temp = String::new();
'的范围仍然存在,即使我在后面通过循环中的'let temp = temp.trim().parse::<f32>();
''影响'它?
Q2。如何重写代码以便返回&str?
fn gettemp() -> f32 {
let temp = String::new();
loop {
println!("What is your temperature?");
io::stdin().read_line(&mut temp).expect("Failed to read the line");
let temp = temp.trim().parse::<f32>();
if !temp.is_ok() {
println!("Not a number!");
} else {
break;
}
}
temp
}
错误:
error[E0308]: mismatched types
--> src/main.rs:70:5
|
49 | fn gettemp() -> f32 {
| --- expected `f32` because of return type
...
70 | temp
| ^^^^ expected f32, found struct `std::string::String`
|
= note: expected type `f32`
found type `std::string::String`
A1 - 不,这不是阴影的作用。让我们看看你的代码与评论。
fn gettemp() -> f32 {
let temp = String::new(); // Outer
loop {
// There's no inner temp at this point, even in the second
// loop pass, etc.
println!("What is your temperature?");
// Here temp refers to the outer one (outside of the loop)
io::stdin().read_line(&mut temp).expect("Failed to read the line");
// Shadowed temp = let's call it inner temp
let temp = temp.trim().parse::<f32>();
// ^ ^
// | |- Outer temp
// |- New inner temp
// temp refers to inner temp
if !temp.is_ok() {
println!("Not a number!");
} else {
// Inner temp goes out of scope
break;
}
// Inner temp goes out of scope
}
// Here temp refers to outer one (String)
temp
}
A2 - 你不能返回&str
。 @ E_net4发布了答案的链接原因。但是,您可以返回String
。你可以做类似的事情,如果你想要有一个经过验证的String
:
fn gettemp() -> String {
loop {
println!("What is your temperature?");
let mut temp = String::new();
io::stdin()
.read_line(&mut temp)
.expect("Failed to read the line");
let trimmed = temp.trim();
match trimmed.parse::<f32>() {
Ok(_) => return trimmed.to_string(),
Err(_) => println!("Not a number!"),
};
}
}
我在你的代码中看到了另外几个问题。
let temp = String::new();
应该是let mut temp
,因为你想稍后借用可变参考(在&mut temp
电话中read_line
)。
另一个问题是qazxsw poi&qazxsw poi。 qazxsw poi附加到loop
。运行此代码......
read_line
...例如输入read_line
。你会看到以下输出......
String
......这不是你想要的。我用这种方式重写了let mut temp = "foo".to_string();
io::stdin().read_line(&mut temp).unwrap();
println!("->{}<-", temp);
:
10
恕我直言显示->foo10
<-
更清洁和可读(相比于建议突破循环的值)。
A3 - 为什么我们不需要在gettemp()
明确陈述fn gettemp() -> f32 {
loop {
println!("What is your temperature?");
let mut temp = String::new();
io::stdin()
.read_line(&mut temp)
.expect("Failed to read the line");
match temp.trim().parse() {
Ok(temp) => return temp,
Err(_) => println!("Not a number!"),
};
}
}
它是由编译器推断的。
return temp
关于问题1,你可以用一个值<f32>
离开循环:
temp.trim().parse()
这样,整个循环的值就是你与fn gettemp() -> f32 { // 1. f32 is return type
loop {
println!("What is your temperature?");
let mut temp = String::new();
io::stdin()
.read_line(&mut temp)
.expect("Failed to read the line");
match temp.trim().parse() {
// 4. parse signature is pub fn parse<F>(&self) -> Result<F, ...>
// compiler knows it must be Result<f32, ...>
// Result<f32, ...> = Result<F, ...> => F = f32
// F was inferred and there's no need to explicitly state it
Ok(temp) => return temp,
// | |
// | 2. return type is f32, temp must be f32
// |
// | 3. temp must be f32, the parse result must be Result<f32, ...>
Err(_) => println!("Not a number!"),
};
}
}
一起传递的东西。
关于问题2,我不确定你是否真的想这样做,因为break
是借来的类型。我想你想在这种拥有数据的情况下返回一个fn gettemp() -> f32 {
let mut temp = String::new();
loop {
println!("What is your temperature?");
io::stdin().read_line(&mut temp).expect("Failed to read the line");
let temp = temp.trim().parse::<f32>();
if !temp.is_ok() {
println!("Not a number!");
} else {
break temp.unwrap() // yield value when breaking out of loop
}
}
}
。
在您的程序中,break
创建了一个新的范围。第二个&str
的范围从它定义的地方开始,并在String
结束时结束。请参阅以下示例:
loop { ... }
这打印2,1。
如果要返回字符串,请使用(代码根据以下注释修复):
temp
loop
是借来的参考。您不能将借用的引用返回到本地变量,该变量将在函数返回时释放。