包含第一、二章
文档:Rust 程序设计语言 - Rust 程序设计语言 简体中文版 (bootcss.com)
墙裂推荐这个文档
第一章入门
入门指南 - Rust 程序设计语言 简体中文版
第二章猜猜看游戏
猜猜看游戏教程 - Rust 程序设计语言 简体中文版 (bootcss.com)
// 导入库
use std::io;
use std::cmp::Ordering;
use rand::Rng;
fn main() {
println!("Guess the number!");
// 生成一个随机数,范围在[1, 100],,需要在配置文toml中加依赖
let secret_number = rand::thread_rng().gen_range(1, 101);
// loop循环
loop {
println!("Please input your guess.");
// 定义一个可变变量,加mut是可变的,不加mut是不可变的
let mut guess = String::new();
// 读一行数据到guess中,返回值是Result(枚举,成员是Ok和Err)
// Result 拥有expect方法
// 如果 io::Result 实例的值是 Err,expect 会导致程序崩溃,并显示当做参数传递给 expect 的信息。
// 如果 read_line 方法返回 Err,则可能是来源于底层操作系统错误的结果。如果 io::Result 实例的值是 Ok,expect 会获取 Ok 中的值并原样返回。
io::stdin().read_line(&mut guess)
.expect("Failed to read line");
// Rust 允许用一个新值来 隐藏 (shadow) guess 之前的值
// String 实例的 trim 方法会去除字符串开头和结尾的空白字符。
// 字符串的 parse 方法 将字符串解析成数字。
// parse也是有返回值,成功的话就是返回num,失败则继续输入
let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => continue,
};
println!("You guessed: {}", guess);
// 用match来匹配
match guess.cmp(&secret_number) {
Ordering::Less => println!("Too small!"), // guess < secret_number
Ordering::Greater => println!("Too big!"),
Ordering::Equal => {
println!("You win!"); // 匹配,跳出循环
break;
}
}
}
}
代码量不大,学了不少语法
测试
第三章常见编程概念
3.1 变量与可变性
变量不可改
fn main() {
println!("Hello, world!");
let i = 3;
println!("i = {}", i);
i = 23; // 变量不可以更改
println!("i = {}", i);
}
结果
可变变量,可以修改
fn main() {
println!("Hello, world!");
let mut i = 3;
println!("i = {}", i);
i = 23;
println!("i = {}", i);
}
变量与常量的区别
(1)不允许对常量使用mut;
(2)声明常量使用 const
关键字而不是 let
,并且 必须 注明值的类型;
(3)常量可以在任何作用域中声明;
(4)常量只能被设置为常量表达式,而不能是函数调用的结果,或任何其他只能在运行时计算出的值。
const MAX_POINTS : u32 = 100_100;
隐藏(Shadowing)
fn main() {
let x = 5;
let x = x + 1;
let x = x * 2;
println!("The value of x is: {}", x);
}
隐藏与将变量标记为 mut
是有区别的。当不小心尝试对变量重新赋值时,如果没有使用 let
关键字,就会导致编译时错误。通过使用 let
,我们可以用这个值进行一些计算,不过计算完之后变量仍然是不变的。
mut
与隐藏的另一个区别是,当再次使用 let
时,实际上创建了一个新变量,我们可以改变值的类型,但复用这个名字。
3.2 数据类型
标量类型 标量(scalar)类型代表一个单独的值。Rust 有四种基本的标量类型:整型、浮点型、布尔类型和字符类型。
整数
长度 | 有符号 | 无符号 |
---|---|---|
8-bit | i8 | u8 |
16-bit | i16 | u16 |
32-bit | i32 | u32 |
64-bit | i64 | u64 |
128-bit | i128 | u128 |
arch | isize | usize |
整形字面值
数字字面值 | 例子 |
---|---|
Decimal | 98_222 |
Hex | 0xff |
Octal | 0o77 |
Binary | 0b1111_0000 |
Byte (u8 only) | b'A' |
浮点型
Rust 也有两个原生的 浮点数(floating-point numbers)类型,它们是带小数点的数字。Rust 的浮点数类型是 f32
和 f64
,分别占 32 位和 64 位。默认类型是 f64
,因为在现代 CPU 中,它与 f32
速度几乎一样,不过精度更高。
Rust 中的所有数字类型都支持基本数学运算:加法、减法、乘法、除法和取余。
fn main() {
// 加法
let _sum = 5 + 10;
// 减法
let _difference = 95.5 - 4.3;
// 乘法
let _product = 4 * 30;
// 除法
let _quotient = 56.7 / 32.2;
// 取余
let _remainder = 43 % 5;
}
布尔型
正如其他大部分编程语言一样,Rust 中的布尔类型有两个可能的值:true
和 false
。Rust 中的布尔类型使用 bool
表示。
字符类型
在 Rust 中,拼音字母(Accented letters),中文、日文、韩文等字符,emoji(绘文字)以及零长度的空白字符都是有效的 char
值。Unicode 标量值包含从 U+0000
到 U+D7FF
和 U+E000
到 U+10FFFF
在内的值。不过,“字符” 并不是一个 Unicode 中的概念,所以人直觉上的 “字符” 可能与 Rust 中的 char
并不符合。
fn main() {
let c = 'z';
let z = 'ℤ';
let heart_eyed_cat = '😻';
}
复合类型
复合类型(Compound types)可以将多个值组合成一个类型。Rust 有两个原生的复合类型:元组(tuple)和数组(array)
元组是一个将多个其他类型的值组合进一个复合类型的主要方式。元组长度固定:一旦声明,其长度不会增大或缩小。
使用包含在圆括号中的逗号分隔的值列表来创建一个元组。元组中的每一个位置都有一个类型,而且这些不同值的类型也不必是相同的。
fn main() {
let tup: (i32, f64, u8) = (500, 6.4, 1);
let tup = (500, 6.4, 1);
let (x, y, z) = tup;
println!("The value of y is: {}", y);
let x: (i32, f64, u8) = (500, 6.4, 1);
let _five_hundred = x.0; // 解构
let _six_point_four = x.1; // 解构
let _one = x.2; // 解构
}
另一个包含多个值的方式是 数组(array)。与元组不同,数组中的每个元素的类型必须相同。Rust 中的数组与一些其他语言中的数组不同,因为 Rust 中的数组是固定长度的:一旦声明,它们的长度不能增长或缩小。
Rust 中,数组中的值位于中括号内的逗号分隔的列表中。
fn main() {
let a = [1, 2, 3, 4, 5];
let months = ["January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December"];
let a: [i32; 5] = [1, 2, 3, 4, 5];
let first = a[0];
let second = a[1];
let index = 3;
let element = a[index];
println!("The value of element is: {}", element);
}
3.3 函数如何工作
和C++大同小异,这里不同的是具有返回值的函数
fn five() -> i32 {
// 没有return
// 没有分号
5
}
fn main() {
let x = five();
println!("The value of x is: {}", x);
}
3.4 注释
不赘述
3.5 控制流
if-else
fn main() {
let number = 6;
// 注意没有括号
if number % 4 == 0 {
println!("number is divisible by 4");
} else if number % 3 == 0 {
println!("number is divisible by 3");
} else if number % 2 == 0 {
println!("number is divisible by 2");
} else {
println!("number is not divisible by 4, 3, or 2");
}
}
在let语句中使用if
fn main() {
let condition = true;
let number = if condition {
5
} else {
6
};
println!("The value of number is: {}", number);
}
if
的每个分支的可能的返回值都必须是相同类型
循环语句
Rust 有三种循环:loop
、while
和 for
。
loop
fn main() {
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2;
}
};
println!("The result is {}", result);
}
while
fn main() {
let mut number = 3;
while number != 0 {
println!("{}!", number);
number = number - 1;
}
println!("LIFTOFF!!!");
}
for
fn main() {
let a = [10, 20, 30, 40, 50];
for element in a.iter() {
println!("the value is: {}", element);
}
for number in (1..4).rev() {
println!("{}!", number);
}
println!("LIFTOFF!!!");
}
参考:常见编程概念 - Rust 程序设计语言 简体中文版 (bootcss.com)