就在锈书的第三章,“锈蚀”中没有什么好的地方。因此,试图实现一个简单的温度计算器,如这一章中的建议。所以我希望你们能指出你们感觉到的一切
use std::io;
fn main() {
println!("Enter Temperature as 56f or 98c");
let mut usr_inpt = String::new();
io::stdin()
.read_line(&mut usr_inpt)
.expect("can not read user input");
let usr_inpt = usr_inpt.trim_end().to_lowercase();
if usr_inpt.ends_with("f") || usr_inpt.ends_with("c") {
// remove the last indication 56f -> 56 or 56c -> 56
let _temp: String = usr_inpt.chars().take(usr_inpt.len() - 1).collect();
let num: u32 = match _temp.parse() {
Ok(num) => num,
Err(_) => 0,
};
if usr_inpt.ends_with("f") {
println!("celcius -> {}", (num - 32) * 5 / 9);
} else if usr_inpt.ends_with("c") {
println!("farenheit -> {}", num * 9 / 5 + 32);
}
} else {
println!("invalid input");
}
}发布于 2019-01-06 01:38:45
使用std::io;fn main() {println!(“输入温度为56f或98c");让mut usr_inpt = String::new();io::stdin() .read_line(&mut usr_inpt) .expect(”无法读取用户输入“);
我喜欢你在这里使用expect而不是unwrap。它允许一个更好的用户体验,当事情走到一边。如果我吹毛求疵,我会提醒你使用适当的大写和标点符号。
let usr\_inpt = usr\_inpt.trim\_end().to\_lowercase(); if usr\_inpt.ends\_with("f") || usr\_inpt.ends\_with("c") { // remove the last indication 56f -> 56 or 56c -> 56 let \_temp: String = usr\_inpt.chars().take(usr\_inpt.len() - 1).collect();
temp很少是个好名字。如果您的意思是temperature而不是temporary,那么最好把它拼出来。
let num: u32 = match \_temp.parse() { Ok(num) => num, Err(\_) => 0, };
在错误情况下返回零真的是正确的吗?我希望这里的错误情况是由无效的用户输入(或者您以前的解析逻辑中的一个错误)引起的。最好是提醒用户注意这个失败,而不是0的神秘结果。
if usr\_inpt.ends\_with("f") { println!("celcius -> {}", (num - 32) \* 5 / 9); } else if usr\_inpt.ends\_with("c") { println!("farenheit -> {}", num \* 9 / 5 + 32); }
我们又做了一次和上面一样的检查,这闻起来有点奇怪。如果将解析逻辑提取到一个函数中,则只需为每种情况调用它。我可能还会提取适当的fahrenheit_to_celcius和celcius_to_fahrenheit函数。
} else { println!("invalid input"); } }
错误消息应打印到stderr。使用eprintln宏代替。
总之,这是一个不错的第一次尝试。不过,我想看看如何为Fahrenheit和Celsius使用一些类型。解析方法可以返回包含Celsius或Fahrenheit度量的D27。
我还没有在编译器中运行这个程序,但希望它说明了这个想法。
struct Celsius { value: u32 }
impl Celsius {
fn to_farhenheit(&self) -> Farhenheit {
Fahrenheit { value: self.value * 9 / 5 + 32 }
}
}
struct Fahrenheit { value: u32 }
impl Fahrenheit {
fn to_celsius(&self) -> Celsius {
Celsius { value: ( self.value - 32) * 5 / 9 }
}
}
enum Temperature {
Fahrenheit(Fahrenheit),
Celsius(Celsius)
Err(String)
}
fn parse_input(input: &str) -> Temperature {
if input.ends_with("f") {
Fahrenheit { value: parse_num(input) }
} else if input.ends_with(“c”) {
Celsius { value: parse_num(input) }
} else {
Err(“Input invalid. Must end with ‘c’ or ‘f’.”)
}
}
fn parse_num(input: &str) -> u32 {
let temperature: String = usr_inpt.chars().take(usr_inpt.len() - 1).collect();
match temperature.parse() {
Ok(num) => num,
Err(_) => 0,
};
}然后我们把一切都联系在一起。
fn main() {
println!("Enter Temperature as 56f or 98c");
let mut usr_inpt = String::new();
io::stdin()
.read_line(&mut usr_inpt)
.expect("can not read user input");
let temperature = parse_input(usr_inpt.trim_end().to_lowercase());
match temperature {
Temperature::Celsius { celsius } => println!("celcius -> {}", celcius.to_fahrenheit()),
Temperature::Fahrenheit { fahrenheit } => println!(“fahrenheit -> {}”, fahrenheit.to_celsius()),
Err(reason) => eprintln!(reason)
}
}虽然它当然是更多的代码,但它提高了main函数中的抽象级别。
这还提供了从parse_num向用户传播错误的机会(留给读者练习),而不是默默地返回无效的结果。
https://codereview.stackexchange.com/questions/210891
复制相似问题