Rust中文翻译7

去台湾玩儿了一个礼拜,赶紧回来继续翻译吧!

3.1.5 循环

Page 38

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()么?如果我们传入了一个非数字,我们会退出循环.看一下:

Page 39

哈哈!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;

}

}

}

}

Page 40

在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;

}

}

}

}

Page 41

修改的行是这里:

let guess: u32 = match guess.trim().parse() {

Ok(num) => num,

Err(_) => continue,

};

通过把ok().expect()语句转为match陈述式,我们可以实现将"错误时崩溃"转换成"错误时处理",这是我们的通用性做法.parse()方法的返回值是一个枚举类型,就像Ordering一样,但是在这里,每一个结果都有一些和他关联的数据:Ok是成功,Ree是失败.两者都有更多的信息:也就是一个成功整型转换,或者一个错误的类型.在此例中,当我们命中了Ok(num)分支,它会把Ok的值赋值给num变量,然后我们会在操作符右侧返回这个值.在Err分支里,我们不关心错误是什么,我们就只用了一个_来代替错误的名字.这将忽略这个错误,然后continue会让我们开始loop的下一次迭代.

现在,我们应该可以成功运行了!让我们试试吧:

Page 42

漂亮!还有最后一个小问题,我们就完成了猜数字游戏.你可以想想是什么问题么?对了,就是我们不要打印出那个秘密数字.它在测试时很好用,但是会毁了游戏.这里是最终版本:

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;

}

}

}

}

Page 43

3.1.6 完成了!

终于,在这里我们成功完成了猜数字游戏!恭喜你!

我们的第一个工程像你展示了很多:let,match,方法,关联方法,使用外部crates等等.我们的下一个工程会展示更多东西.

时间: 2024-10-03 23:44:34

Rust中文翻译7的相关文章

Rust中文翻译29

5.10 生命期 本节是Rust三处描述所有权系统的其中之一.所有权是Rust最独特和引人注目的特性,这也是Rust程序员必须熟悉的一个特性.所有权使Rust得以实现它最大的设计目标,内存安全.这里有一些不同的概念,每一个都有自己的章节: 所有权,你正在读的 借用(borrowing, 5.9), 以及它的关联特性'引用' 生命期(5.10),以及borrowing的高级特性 这三者是相关的,也是循序渐进的.你必须要完全理解这个三个部分. 5.10.1 元 在我们讨论细节之前,有两个关于所有权系

Rust中文翻译21

4.7 错误处理 有时候程序会发生错误.对于不可避免的事情发生时最好有一个计划来处理.Rust有丰富的处理错误的方法. 你的程序会出现两种类型的错误:失败和崩溃.我们先讨论两者的区别,然后讨论如何处理他们.然后,我们讨论把错误升级为崩溃. Page 107 4.7.1 失败和崩溃 Rust使用两种错误的类型:失败和崩溃.失败是一种可以被挽回的错误.崩溃却不行. "挽回"是什么意思呢?在多数情况下,很有可能会发生错误.例如,一个parse函数: "5".parse()

Rust中文翻译12

Page 63 我们已经学习了如何写一些Rust代码了.但是能写Rust代码和能写好的Rust代码又很大区别. 这一章讲述一些相对独立的指南,告诉你如何把的Rust代码更进一步.一些常用的模式和标准库会被提到.你可以随意安排阅读本章的顺序. 4.1 栈和堆 作为一个系统级别的语言,Rust可以在底层进行操作.如果你来自于高层语言,有一些系统编程概念你可能不太熟悉.最重要的就是内存中的栈和堆是如何工作的.如果你了解类C语言中栈的分配,这一章就是一个回顾.如果你不了解,你可以在本章学习这些概念了,但

Rust中文翻译28

5.9 引用和借用 本节是Rust三处描述所有权系统的其中之一.所有权是Rust最独特和引人注目的特性,这也是Rust程序员必须熟悉的一个特性.所有权使Rust得以实现它最大的设计目标,内存安全.这里有一些不同的概念,每一个都有自己的章节: 所有权,你正在读的 借用(borrowing, 5.9), 以及它的关联特性'引用' 生命期(5.10),以及borrowing的高级特性 这三者是相关的,也是循序渐进的.你必须要完全理解这个三个部分. 5.9.1 元 在我们讨论细节之前,有两个关于所有权系

Rust中文翻译17

4.2.4 文档测试 没有什么比带有示例的文档更好的了.也没有什么比不能工作的例子更糟的了,因为有可能文档中的代码已经修改了.为此,Rust支持自动测试我们示例代码.让我们看一个富有血肉的src/lib.rs的例子: //! The àdder` crate provides functions that add numbers to other numbers. //! //! # Examples //! //! ``` //! assert_eq!(4, adder::add_two(2)

Rust中文翻译15

大多数使用垃圾回收的语言都默认在堆上分配内存.这就意味着每个值都要装箱.有很多原因导致他们这样设计,但是这超出了本书的范围.同样,也有很多优化设计导致它并不是100%这样工作的.垃圾回收器宁愿选择在堆上分配内存,也不使用栈和Drop操作来释放内存. 4.1.7 该用哪一种呢? 所以当栈又快又好用的时候,为什么我们还需要使用堆呢?一个重要的原因是,栈只给你提供了LIFO语义来管理内存.堆分配却可以提供更加通用的和任意的顺序来使用内存,同时附带一些开销. 通常情况下,你应当使用栈,Rust默认就是如

Rust中文翻译20

Page 100 并发和并行在计算机科学中是非常重要的主题.在工业领域也很火.计算机如今有越来越多的核心,然而很多程序员还没有准备好使用它们. Rust安全的内存特性同样适用于并发存储.并发的Rust代码也是内存安全的,没有数据竞争.Rust的类型系统会保证这一点,给你提供了有利的帮助在编译时实现并发代码. 在我们开始讨论Rust的并发之前,我们需要理解一个很重要的事情:Rust是一个低级别语言,它的所有功能都是通过库来提供的,而不是语言自身.也就是说你不喜欢Rust处理并发的方式,你完全可以实

Rust中文翻译34

5.14 Match 经常,一个简单的if/else还不够,因为你可能会有多于两种情况.而且,条件会变得更加复杂.Rust有一个关键字,match,允许你替代复杂的if/else组合,来实现一些更强大的功能.看一下: let x = 5; match x { 1 => println!("one"), 2 => println!("two"), 3 => println!("three"), 4 => println!(&

Rust中文翻译31

5.12 结构体 结构体是一个表示复杂数据类型的方式.例如,你可以计算二维坐标,我们需要x和y的值: let origin_x = 0; let origin_y = 0; 一个结构体就可以让你将两个值合并成一个独立的值: struct Point { x: i32, y: i32, } fn main() { let origin = Point {x: 0, y: 0}; // origin: Point println!("The origin is at ({}, {})",