您的位置:首页 > 运维架构

Rust猜数字之循环

2015-05-13 09:14 441 查看
循环

     loop关键字给我们一个无限循环。让我们添加它:

extern crate rand;

use std::io;
use std::cmp::Ordering;
use rand::Rng;

fn main() {
println!("Guess the number!");

let secret_number = rand::thread_rng().gen_range(1, 101);

println!("The secret number is: {}", secret_number);

loop {
println!("Please input your guess.");

let mut guess = String::new();

io::stdin().read_line(&mut guess)
.ok()
.expect("failed to read line");

let guess: u32 = guess.trim().parse()
.ok()
.expect("Please type a number!");

println!("You guessed: {}", guess);

match guess.cmp(&secret_number) {
Ordering::Less    => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal   => println!("You win!"),
}
}
}

     试一下。但是等等,我们不是仅仅添加了一个死循环吗?是的,但是记住我们讨论的parse()了吗?如果我们给一个非数字答案,我们就爱那个会返回并推出。观察:

$ cargo run
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
Running `target/guessing_game`
Guess the number!
The secret number is: 59
Please input your guess.
45
You guessed: 45
Too small!
Please input your guess.
60
You guessed: 60
Too big!
Please input your guess.
59
You guessed: 59
You win!
Please input your guess.
quit
thread '<main>' panicked at 'Please type a number!'

     哈!quit确实退出了。首先,当你赢的时候实现真正的退出。

extern crate rand;

use std::io;
use std::cmp::Ordering;
use rand::Rng;

fn main() {
println!("Guess the number!");

let secret_number = rand::thread_rng().gen_range(1, 101);

println!("The secret number is: {}", secret_number);

loop {
println!("Please input your guess.");

let mut guess = String::new();

io::stdin().read_line(&mut guess)
.ok()
.expect("failed to read line");

let guess: u32 = guess.trim().parse()
.ok()
.expect("Please type a number!");

println!("You guessed: {}", guess);

match guess.cmp(&secret_number) {
Ordering::Less    => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal   => {
println!("You win!");
break;
}
}
}
}

     通过在You win!后面添加break,当我们胜利时将会退出循环。退出循环也意味着退出程序,因为它是main()中最后的事情。我们还要做一个修正:当有人输入的是非数字的时候,我们不想退出,我们只想忽略它。我们可以这样做:

extern crate rand;

use std::io;
use std::cmp::Ordering;
use rand::Rng;

fn main() {
println!("Guess the number!");

let secret_number = rand::thread_rng().gen_range(1, 101);

println!("The secret number is: {}", secret_number);

loop {
println!("Please input your guess.");

let mut guess = String::new();

io::stdin().read_line(&mut guess)
.ok()
.expect("failed to read line");

let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => continue,
};

println!("You guessed: {}", guess);

match guess.cmp(&secret_number) {
Ordering::Less    => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal   => {
println!("You win!");
break;
}
}
}
}

     这些是改变的行:

let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => continue,
};

     这是你通常从‘遇到错误退出’变成‘实际处理错误’,通过从ok().expect()转换成一个match声明。通过parse()返回的Result是一个枚举类型类似于Ordering,但是在这种情况下,每一中变化都有一些数据与之关联:Ok是成功,Err是失败。每个包含更多信息:正确解析整数或者一个错误类型。在这种情况下,我们匹配Ok(num),将Ok的内部值设置成num,并且我们仅仅在右边返回它即可。在Err的情况下,我们不关心是什么样的错误,所以我们使用_代替一个名字。忽略错误,continue将会进入下一次循环迭代。

     现在应该是好使的!让我们试试:

$ cargo run
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
Running `target/guessing_game`
Guess the number!
The secret number is: 61
Please input your guess.
10
You guessed: 10
Too small!
Please input your guess.
99
You guessed: 99
Too big!
Please input your guess.
foo
Please input your guess.
61
You guessed: 61
You win!

     非常了不起!还有一处需要修正,我们已经完成了猜数字的游戏。你能想出这一处是什么吗?对的,我们不想打印出神秘数字。对于测试它是好的,但是它毁掉了游戏。这是我们的最终代码:

extern crate rand;

use std::io;
use std::cmp::Ordering;
use rand::Rng;

fn main() {
println!("Guess the number!");

let secret_number = rand::thread_rng().gen_range(1, 101);

loop {
println!("Please input your guess.");

let mut guess = String::new();

io::stdin().read_line(&mut guess)
.ok()
.expect("failed to read line");

let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => continue,
};

println!("You guessed: {}", guess);

match guess.cmp(&secret_number) {
Ordering::Less    => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal   => {
println!("You win!");
break;
}
}
}
}


结束语

     到这里,你已经成功构建了猜数字游戏!恭喜!

     第一个项目展示了很多东西:let、match、方法、关联函数、使用外部crate等等。我们下一个项目将会展示更多。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Rust Mozilla 循环 loop break