gpt4 book ai didi

rust - 具有阴影和 String -> &str 转换的 'let' 范围

转载 作者:行者123 更新时间:2023-11-29 08:26:36 25 4
gpt4 key购买 nike

使用以下代码,我试图返回用户输入的温度 &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`

最佳答案

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 .你可以做类似这个 nn 的事情,你想要一个经过验证的 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 tempread_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()这样:

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更清晰易读(与建议的使用值跳出循环相比)。


A3 - 为什么我们不需要明确说明 <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!"),
};
}
}

关于rust - 具有阴影和 String -> &str 转换的 'let' 范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55043020/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com