Rust 程序设计语言文档学习

环境搭建

参考:Windows10配置Rust开发环境

项目目录

默认cargo新建工程之后会有以下文件

  • src/:源代码文件夹
  • src/main.rs:程序入口
  • target/:用来存放debug/release时的文件,通常不需要我们手动编辑
  • .gitignore:Git中忽略文件和文件夹
  • Cargo.lock:由cargo维护的项目相关依赖的具体信息,不需要我们手动编辑
  • Cargo.toml:由我们编辑的项目名称、项目版本、项目作者,以及项目所需相关依赖

Hello World

1
2
3
fn main() {
println!("hello world")
}

命名规则

下划线分隔的大写字母单词:常量、全局变量

下划线分隔的小写字母单词:变量、函数、模块、文件、目录

大驼峰:结构体、枚举、Trait

数据类型

标量类型

标量类型:整型、浮点型、布尔类型、字符类型

整型

长度 有符号 无符号
8-bit i8 u8
16-bit i16 u16
32-bit i32(默认) u32
64-bit i64 u64
128-bit i128 u128
arch isize usize

浮点型

f32和f64(默认)

布尔类型

bool

字符类型

char

大小:4个字节

复合类型

复合类型:元组(tuple)和数组(array)

元组类型

特点:长度固定

数组类型

特点:每个元素的类型必须相同,长度固定

函数

1
2
3
fn 函数名(参数名:参数类型) -> 返回值类型 {
返回值
}

判断/循环

if(else if)、loop(重复执行)、break(跳出循环)、continue(跳出当前循环)、while(条件循环)、for in(遍历)

所有权

  1. Rust 中的每一个值都有一个 所有者(owner)
  2. 值在任一时刻有且只有一个所有者
  3. 当所有者(变量)离开作用域,这个值将被丢弃

引用

  1. 在任意给定时间,要么 只能有一个可变引用,要么 只能有多个不可变引用
  2. 引用必须总是有效的

Slice

slice 允许你引用集合中一段连续的元素序列,而不用引用整个集合。slice 是一类引用,所以它没有所有权。

1
2
3
4
5
6
7
8
fn main() {
let s = String::from("hello world");

let hello = &s[0..5];
let world = &s[6..11];

println!("{} {}", hello, world)
}

结构体

struct

结构体中字段定义字符串,使用拥有所有权的 String 类型而不是 &str

面向对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
fn main() {
let rect1 = Rectangle {
width: 30,
height: 50,
};
println!("The area of the rectangle is {} square pixels.", rect1.area()
);
}

struct Rectangle {
width: u32,
height: u32,
}

impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
}

枚举

1
2
3
4
5
6
7
8
fn main() {
enum IpAddrKind {
V4(u32, u32, u32, u32),
V6(String),
}
let four = IpAddrKind::V4(128, 0, 0, 1);
let six = IpAddrKind::V6(String::from("::1"));
}

模式匹配

match、Option、Some、_(占位符)

简洁控制流

if let

模块

use、mod、pub、as(别名)

集合

Vec和HashMap

错误处理

panic!、Result

简写:unwrap、expect

expect 与 unwrap 的使用方式一样:返回文件句柄或调用 panic! 宏。expect 在调用 panic! 时使用的错误信息将是我们传递给 expect 的参数,而不像 unwrap 那样使用默认的 panic! 信息

泛型

Rust 通过在编译时进行泛型代码的 单态化(monomorphization)来保证效率。单态化是一个通过填充编译时使用的具体类型,将通用代码转换为特定代码的过程。

Trait

类似其他编程语言中的接口(interface)

1
2
3
pub trait Summary {
fn summarize(&self) -> String;
}

默认实现

1
2
3
4
5
pub trait Summary {
fn summarize(&self) -> String {
String::from("(Read more...)")
}
}

生命周期

自动化测试

#[cfg(test)]、#[test]

#[ignore]:排除指定的测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#[cfg(test)]
mod tests {
#[test]
fn test1() {
println!("this is test1")
}

#[test]
#[ignore]
fn test2() {
println!("this is test2")
}

#[test]
fn test3() {
println!("this is test3")
}
}

IO

接口命令行参数

1
2
3
4
fn main() {
let args: Vec<String> = env::args().collect();
dbg!(args);
}

读取文件内容

1
2
3
4
5
6
7
8
use std::fs;

fn main() {
let file_path = "新建文本文档.txt";
let contents = fs::read_to_string(file_path)
.expect("Should have been able to read the file");
println!("{}", contents)
}

迭代器

1
2
3
4
5
fn main() {
let v1: Vec<i32> = vec![1, 2, 3];
let v2: Vec<i32> = v1.iter().map(|x| x + 1).collect();
println!("{:?}", v2);
}

闭包

1
2
3
4
5
6
7
8
9
fn main() {
let mut list = vec![1, 2, 3];
println!("Before defining closure: {:?}", list);

let mut borrows_mutably = || list.push(7);

borrows_mutably();
println!("After calling closure: {:?}", list);
}

并发

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
use std::sync::mpsc;
use std::thread;
use std::time::Duration;

fn main() {
let (tx, rx) = mpsc::channel();

thread::spawn(move || {
let vals = vec![
String::from("hi"),
String::from("from"),
String::from("the"),
String::from("thread"),
];

for val in vals {
tx.send(val).unwrap();
thread::sleep(Duration::from_secs(1));
}
});

for received in rx {
println!("Got: {}", received);
}
}