首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >猜锈游戏

猜锈游戏
EN

Code Review用户
提问于 2015-03-24 22:13:45
回答 2查看 1.3K关注 0票数 7

我是否很好地使用了锈蚀语言和API?还有什么可以改进的?

代码语言:javascript
复制
extern crate rand;

use std::old_io;

fn main() {
    println!("Guessing Game");
    // declaring the type in the left side of let helps random() return the right datatype
    // An alternative is: let answer = (rand::random::<u32>() % 100) + 1;
    let answer: u8 = (rand::random() % 100) + 1;
    let mut guess: String;
    let mut guess_cast: Result<u8, _>;

    loop {
        guess = guesser();
        guess_cast = guess.trim().parse();

        let guess_num = match guess_cast {
            Ok(num) => num,
            Err(_) => { println!("Guess was not a number, try again"); continue; }
        };

        if guess_num < answer { println!("Too low") }
        else if guess_num > answer { println!("Too high") }
        else { println!("You guessed it!"); return; }
    }
}

fn guesser() -> String {
    println!("Guess a number between 0 and 100: ");
    old_io::stdin().read_line().ok().expect("Error getting user input")
}
EN

回答 2

Code Review用户

回答已采纳

发布于 2015-03-25 01:27:18

这里或多或少是我要写的东西:

代码语言:javascript
复制
extern crate rand;

use std::io::{self, Write};

fn main() {
    println!("Guessing Game");
    let answer: u8 = (rand::random() % 100) + 1;

    loop {
        print!("Guess a number between 1 and 100: ");
        let _ = io::stdout().flush();
        let mut input = String::new();
        io::stdin().read_line(&mut input).ok().expect("Error getting user input");

        let guess = match input.trim().parse() {
            Ok(num) => num,
            Err(_) => {
                println!("Guess was not a number, try again");
                continue;
            },
        };

        if guess < answer {
            println!("Too low");
        } else if guess > answer {
            println!("Too high");
        } else {
            println!("You guessed it!");
            return;
        }
    }
}

我可以用这个代替整个if块(加上use std::cmp::Ordering;let guess上的: u8 ):

代码语言:javascript
复制
        match guess.cmp(&answer) {
            Ordering::Less => println!("Too low"),
            Ordering::Greater => println!("Too high"),
            Ordering::Equal => {
                println!("You guessed it!");
                return;
            },
        }

有许多变化,大多是微妙的;有些我会评论,另一些我可能会忽略:

  • 确保你的界限是正确的(0不是一个可能的数字)。
  • 别用std::old_io,它就快出来了。
  • 只要显式地刷新stdout,就可以在与查询相同的行上获得输入。
  • 在生成()时,更喜欢块末尾的分号(我指的是类似于if块中的情况)。
  • 使用if语句,要么将整件事情放在一行上,要么在{之后完成每一行。
  • 避免将多个语句放在同一行中。
  • 只有当您要在循环之后使用let mut a; loop { a = …; … }的值时,才应该使用a而不是loop { let a = …; … }。最大限度地缩小定义和声明之间的距离,并在可能的情况下合并两者是非常可取的。顺便说一句,任何你可以在没有卷积的情况下丢弃mut的地方也应该被取走。
  • 将用户输入分成一个单独的函数似乎没有多大意义。
  • 在转换其格式时,使用具有多种后缀的相同变量名是可以的,但如果可能的话,可以找到更好的名称。在执行多个步骤时,考虑合并一些行(guess_cast对我来说似乎是多余的)。我选择input作为用户输入,选择guess作为结果,在我看来,这一安排既清晰又简单。

如果希望最小化分配,可以将input定义从循环中移出,并将循环中的分配替换为input.clear()。这样,它就可以一次又一次地使用相同的堆分配。但这是一种优化,这种优化对于这样的事情来说是不必要的。我可能做,也可能不做,这取决于我吃了什么,如果有的话,作为早茶。

就我个人而言,我认为在这种情况下,我会使用break而不是return,但这完全是主观的。

票数 6
EN

Code Review用户

发布于 2015-04-11 15:08:00

除了现有的答案之外,我还鼓励您使用兰德的Range生成器:

代码语言:javascript
复制
fn answer() -> u8 {
    let between = Range::new(0, 100);
    let mut rng = rand::thread_rng();
    between.ind_sample(&mut rng) + 1
}

我更喜欢在一个范围内明确要求一个随机数的表现力,但是有一个更大的好处:这实际上生成了一个统一的样本!换句话说,它可以让您避免使用模偏置

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

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

复制
相关文章

相似问题

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