使用以下代码,我试图返回&str用户输入的温度,但徒劳。然后,我试图返回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`
答案 0 :(得分:1)
关于问题1,您可以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
一起传递的东西。
关于问题2,我不确定您是否真的想这样做,因为&str
是借来的类型。我认为您想在这种情况下返回一个拥有数据的String
。
答案 1 :(得分:1)
A1-不,这不是阴影的工作原理。让我们看看带有注释的代码。
package Lab5;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashSet;
import java.util.Scanner;
public class Lorem {
public static void main(String[] args) {
String[] loremIpsum = null;
try {
loremIpsum = new Scanner(new File("loremIpsum.txt")).next().split(" ");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
System.out.println(loremIpsum.length);
HashSet h = new HashSet();
for(int i=0;i<loremIpsum.length;i++) {
String word=loremIpsum[i];
System.out.println(word);
if(h.contains(word)) {
System.out.println("we found a duplicate");
} else {
h.add(word);
}
}
}
}
A2-您无法返回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
}
。 @ E_net4发布了答案的链接。但是,您可以返回&str
。您可以执行以下操作,以使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
和loop
。 read_line
追加到read_line
。运行此代码...
String
...,然后输入let mut temp = "foo".to_string();
io::stdin().read_line(&mut temp).unwrap();
println!("->{}<-", temp);
。您将看到以下输出...
10
...这不是您想要的。我将以这种方式重写->foo10
<-
:
gettemp()
IMHO显式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!"),
};
}
}
更清晰易读(与建议使用一个值冲破循环相比)。
A3-为什么我们不需要在return temp
中明确声明<f32>
由编译器推断。
temp.trim().parse()
答案 2 :(得分:0)
在您的程序中,loop { ... }
创建一个新范围。第二个temp
的范围从定义的地方开始,到loop
结束时结束。请参见以下示例:
fn main() {
let a = 1;
{
let a = 2;
println!("{}", a);
}
println!("{}", a);
}
这将打印2、1。
如果要返回字符串,请使用(代码根据下面的注释固定):
fn gettemp() -> String {
loop {
let mut temp = String::new();
println!("What is your temperature?");
std::io::stdin().read_line(&mut temp).expect("Failed to read the line");
temp = temp.trim().to_string();
match temp.parse::<f32>() {
Err(_) => println!("Not a number!"),
_ => return temp,
}
}
}
&str
是借用的参考。您不能返回借用的对局部变量的引用,该引用将在函数返回时释放。