首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >锈蚀温度计算器

锈蚀温度计算器
EN

Code Review用户
提问于 2019-01-04 17:41:41
回答 1查看 313关注 0票数 3

就在锈书的第三章,“锈蚀”中没有什么好的地方。因此,试图实现一个简单的温度计算器,如一章中的建议。所以我希望你们能指出你们感觉到的一切

代码语言:javascript
复制
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");
    }
}
EN

回答 1

Code Review用户

发布于 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_celciuscelcius_to_fahrenheit函数。

} else { println!("invalid input"); } }

错误消息应打印到stderr。使用eprintln代替。

总之,这是一个不错的第一次尝试。不过,我想看看如何为FahrenheitCelsius使用一些类型。解析方法可以返回包含CelsiusFahrenheit度量的D27

我还没有在编译器中运行这个程序,但希望它说明了这个想法。

代码语言:javascript
复制
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,
    };
}

然后我们把一切都联系在一起。

代码语言:javascript
复制
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向用户传播错误的机会(留给读者练习),而不是默默地返回无效的结果。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/210891

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档