当你想学习一门新的编程语言时,最好专注于编程语言的共同之处
- 变量
- 表达式
- 语句
这些概念是大多数编程语言的基础。一旦你理解了它们,你就可以开始弄清楚其余的部分。
因为编程语言通常具有相似之处,所以一旦你掌握了一种语言,你就可以通过理解其差异来学习另一种语言的基础知识。
学习新语言的一个好方法是使用一个你可以用来练习的标准程序。这使你可以专注于语言本身,而不是程序的逻辑。在本系列文章中,我正在使用一个“猜数字”程序来做到这一点,在这个程序中,计算机会选择一个 1 到 100 之间的数字,并要求你猜这个数字。程序会循环,直到你猜对数字为止。
这个程序练习了编程语言中的几个概念
- 变量
- 输入
- 输出
- 条件评估
- 循环
这是一个学习新编程语言的绝佳实践实验。
安装 Rust
你可以使用 Rustup 安装 Rust 工具链,或者你可以在线试用 Rust,而无需在本地安装。
如果你在本地安装了 Rust,你应该定期使用 rustup update
更新它,以保持你的工具链最新,并使用 cargo update
更新你的库到最新版本。
用 Rust 猜数字
Rust 是一种使任何人都能构建可靠且高效软件的语言。你可以通过编写一个“猜数字”游戏的版本来探索 Rust。
第一步是编写一个 Cargo.toml
文件。你可以使用 cargo new
命令生成一个 Cargo.toml
骨架。这几乎总是启动 Rust 项目的最佳方式。
$ cargo new guess
$ cd guess
$ ls -1
Cargo.toml
src/
Cargo.toml
文件命名你的包,为其提供一些元数据,最重要的是,指定它依赖于 rand
crate。
[package]
name = "guess"
version = "2020.11.0"
authors = ["Moshe Zadka <moshez@opensource.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.net.cn/cargo/reference/manifest.html
[dependencies]
rand = "*"
Rust 中的许多东西都不是由语言或标准库提供的。相反,你可以从许多外部 crate 中获得它们,这些 crate 可以完成许多事情。
程序逻辑放在 src/main.rs
中
use rand::Rng;
use std::io::BufRead;
fn main() {
let mut rng = rand::thread_rng();
let random = rng.gen_range(1..101);
println!("Guess a number between 1 and 100");
for line in std::io::stdin().lock().lines() {
let parsed = line.ok().as_deref().map(str::parse::<i64>);
if let Some(Ok(guess)) = parsed {
match guess {
_ if guess < random => println!("Too low"),
_ if guess > random => println!("Too high"),
_ => {
println!("That's right");
break;
}
}
}
}
}
代码的前两行声明了你要做什么。在本例中,rand::Rng
生成一个猜测,而 trait std::io::BufRead
允许从标准输入读取。
Rust 代码的入口点在 main()
函数中,所以下一步是定义 main()
。
要为变量赋值,请使用 let
,然后是变量的名称,后跟 =
符号。这将创建一个不可变变量。
你的大多数变量将是不可变的,但 rng
对象必须是可变的。例如,语句 let random = 0
将零值赋给 random
变量。
函数的第一行创建一个线程安全的 Rng
对象,并将其赋值给变量 rng
。Rust 构建于线程和内存安全之上,因此你必须在开始编写代码时就考虑这些事情。
程序的下一行读取函数 gen_range()
的结果,并将其赋值给名为 random
的变量。该函数接受一个最小值(包含)和一个上限(不包含)。为了使上限包含在内,你可以用等号标记较大的数字(例如,1..=100
),或者你可以像我在代码中所做的那样,将上限设置为比你的预期最大值高 1。在本例中,范围是 1
到 100
,使游戏具有足够的挑战性。
中心循环遍历 std::io::stdin()
中的行。由于可能存在各种可能导致行无法读取的极端情况,Rust 要求你使用 Result
包装一行。行也可能无法解析为整数。
此代码使用条件模式匹配来忽略所有可能导致错误的行
let parsed = line.ok().as_deref().map(str::parse::<i64>);
if let Some(Ok(guess)) = parsed {
// ...
}
第一行创建一个 Result<Option<i64>, ...>
对象,因为它可能在读取或解析步骤中失败。由于下一行仅匹配 Some(Ok(guess))
,因此每当一行产生不匹配的值时,它都会跳过 if
语句。这是一种忽略错误的强大方法。
Rust 支持条件表达式和流程控制,例如循环。在“猜数字”游戏中,只要猜测值不等于 random
,Rust 就会继续循环。
if
语句的主体包含使用 Rust 的 match
语句的三向分支。虽然 match
最常用于模式匹配,但它也可以检查任意条件。在这种情况下,如果猜测正确,则打印适当的消息并 break
循环。
示例输出
现在你已经编写了你的 Rust 程序,你可以运行它来玩“猜数字”游戏。每次你运行程序时,Rust 都会选择一个不同的随机数,所以继续猜测直到你找到正确的数字
$ cargo run
Compiling guess v2020.11.0 (/Users/mzadka/src/guess)
Finished dev [unoptimized + debuginfo] target(s) in 0.70s
Running `target/debug/guess`
Guess a number between 1 and 100
50
Too high
25
Too high
12
Too low
18
Too high
15
Too high
13
Too low
14
That's right
通常通过运行 cargo run
来测试程序。最终,你可能会使用 cargo build
来 构建可执行文件并将其作为两个独立的步骤运行。
学习 Rust
“猜数字”游戏是学习新编程语言的一个很好的入门程序,因为它以一种非常直接的方式练习了几个常见的编程概念。通过用不同的编程语言实现这个简单的游戏,你可以展示这些语言的一些核心概念,并比较它们的细节。
你有没有最喜欢的编程语言?你会用它怎么编写“猜数字”游戏?关注本系列文章,了解其他你可能感兴趣的编程语言的示例!
2 条评论