Rust 知识速查表
本页面汇总了 Rust 编程中最常用的语法和知识点,方便快速查阅。
变量
// 不可变变量
let x = 5;
// 可变变量
let mut x = 5;
x = 6;
// 常量
const MAX_POINTS: u32 = 100_000;
// 变量遮蔽
let x = 5;
let x = x + 1;
let x = "现在 x 是字符串"; // 可以改变类型
数据类型
标量类型
// 整数
let a: i32 = -5; // 有符号 32 位
let b: u32 = 5; // 无符号 32 位
let c: isize = 10; // 指针大小
// 浮点数
let f1: f32 = 3.14;
let f2: f64 = 3.14159265359; // 默认
// 布尔
let t = true;
let f: bool = false;
// 字符
let c = 'z';
let emoji = '😻';
复合类型
// 元组
let tup: (i32, f64, u8) = (500, 6.4, 1);
let (x, y, z) = tup;
let first = tup.0;
// 数组
let arr = [1, 2, 3, 4, 5];
let arr: [i32; 5] = [1, 2, 3, 4, 5];
let repeat = [3; 5]; // [3, 3, 3, 3, 3]
let first = arr[0];
函数
// 无返回值
fn print_sum(a: i32, b: i32) {
println!("Sum: {}", a + b);
}
// 有返回值
fn add(a: i32, b: i32) -> i32 {
a + b // 隐式返回,无分号
}
// 提前返回
fn abs(x: i32) -> i32 {
if x < 0 { return -x; }
x
}
控制流
if 表达式
let number = 6;
if number % 4 == 0 {
println!("divisible by 4");
} else if number % 3 == 0 {
println!("divisible by 3");
} else {
println!("not divisible by 4 or 3");
}
// if 作为表达式
let condition = true;
let number = if condition { 5 } else { 6 };
循环
// loop
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2; // 返回值
}
};
// while
while number != 0 {
println!("{}!", number);
number -= 1;
}
// for
for element in a.iter() {
println!("{}", element);
}
for number in 1..4 {
println!("{}", number); // 1, 2, 3
}
for number in (1..4).rev() {
println!("{}", number); // 3, 2, 1
}
match 表达式
match number {
1 => println!("One"),
2 | 3 | 5 | 7 => println!("Prime"),
13..=19 => println!("Teen"),
_ => println!("Other"), // 默认
}
// match 返回值
let binary = match boolean {
false => 0,
true => 1,
};
if let
// 简化 match
if let Some(3) = some_value {
println!("Three");
}
// 带 else
if let Some(x) = some_value {
println!("Value is {}", x);
} else {
println!("None");
}
所有权
移动
let s1 = String::from("hello");
let s2 = s1; // s1 移动到 s2
// println!("{}", s1); // 错误!
克隆
let s1 = String::from("hello");
let s2 = s1.clone(); // 深度复制
println!("{} {}", s1, s2); // 都有效
Copy 类型
let x = 5;
let y = x; // 复制
println!("{} {}", x, y); // 都有效
// Copy 类型:整数、浮点、布尔、字符、不可变引用
引用与借用
// 不可变引用
fn len(s: &String) -> usize {
s.len()
}
// 可变引用
fn push(s: &mut String) {
s.push_str(" world");
}
// 规则:可变引用和不可变引用不能同时存在
let mut s = String::from("hello");
let r1 = &s;
let r2 = &s;
println!("{} {}", r1, r2); // r1, r2 最后使用
let r3 = &mut s; // 正确
切片
// 字符串切片
let s = String::from("hello world");
let hello = &s[0..5];
let world = &s[6..11];
let whole = &s[..];
// 数组切片
let a = [1, 2, 3, 4, 5];
let slice = &a[1..3]; // [2, 3]
结构体
struct User {
username: String,
email: String,
active: bool,
}
// 创建
let user1 = User {
email: String::from("[email protected]"),
username: String::from("user"),
active: true,
};
// 更新语法
let user2 = User {
email: String::from("[email protected]"),
..user1 // 其余字段来自 user1
};
// 元组结构体
struct Point(i32, i32, i32);
let origin = Point(0, 0, 0);
// 单元结构体
struct AlwaysEqual;
枚举
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}
// 使用
let msg = Message::Move { x: 1, y: 2 };
match msg {
Message::Quit => println!("Quit"),
Message::Move { x, y } => println!("Move to ({}, {})", x, y),
Message::Write(text) => println!("Text: {}", text),
Message::ChangeColor(r, g, b) => println!("Color: ({}, {}, {})", r, g, b),
}
// Option 枚举
enum Option<T> {
Some(T),
None,
}
// Result 枚举
enum Result<T, E> {
Ok(T),
Err(E),
}
错误处理
panic
panic!("crash and burn");
Result
use std::fs::File;
use std::io::ErrorKind;
// match 处理
let f = File::open("hello.txt");
let f = match f {
Ok(file) => file,
Err(error) => match error.kind() {
ErrorKind::NotFound => match File::create("hello.txt") {
Ok(fc) => fc,
Err(e) => panic!("Problem creating the file: {:?}", e),
},
other_error => panic!("Problem opening the file: {:?}", other_error),
},
};
// unwrap:Ok 返回值,Err 则 panic
let f = File::open("hello.txt").unwrap();
// expect:自定义错误信息
let f = File::open("hello.txt").expect("Failed to open hello.txt");
// ? 运算符:传播错误
fn read_username_from_file() -> Result<String, io::Error> {
let mut f = File::open("hello.txt")?;
let mut s = String::new();
f.read_to_string(&mut s)?;
Ok(s)
}
泛型
// 泛型函数
fn largest<T: PartialOrd>(list: &[T]) -> &T {
let mut largest = &list[0];
for item in list {
if item > largest {
largest = item;
}
}
largest
}
// 泛型结构体
struct Point<T> {
x: T,
y: T,
}
// 泛型枚举
enum Option<T> {
Some(T),
None,
}
Trait
// 定义 trait
trait Summary {
fn summarize(&self) -> String;
}
// 实现 trait
impl Summary for Article {
fn summarize(&self) -> String {
format!("{}, by {}", self.title, self.author)
}
}
// 默认实现
trait Summary {
fn summarize(&self) -> String {
String::from("(Read more...)")
}
}
// Trait 作为参数
fn notify(item: &impl Summary) {
println!("{}", item.summarize());
}
// Trait bound
fn notify<T: Summary>(item: &T) {
println!("{}", item.summarize());
}
// 多个 trait
fn notify(item: &(impl Summary + Display)) {}
fn notify<T: Summary + Display>(item: &T) {}
// where 子句
fn some_function<T, U>(t: &T, u: &U) -> i32
where
T: Display + Clone,
U: Clone + Debug,
{
// ...
}
生命周期
// 生命周期标注
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() { x } else { y }
}
// 结构体中的生命周期
struct ImportantExcerpt<'a> {
part: &'a str,
}
// 静态生命周期
let s: &'static str = "I have a static lifetime.";
模块系统
// 模块定义
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
// 使用
use crate::front_of_house::hosting;
use self::front_of_house::hosting;
// 重命名
use std::fmt::Result as FmtResult;
// 嵌套路径
use std::io::{self, Write};
use std::collections::{HashMap, BTreeMap, HashSet};
// 导出所有
use std::collections::*;
常用标准库
Vec
let mut v = Vec::new();
v.push(1);
v.push(2);
let v = vec![1, 2, 3];
let third = &v[2]; // 索引访问
let third = v.get(2); // 返回 Option<&T>
for i in &v {
println!("{}", i);
}
for i in &mut v {
*i += 50;
}
String
let mut s = String::new();
let s = String::from("hello");
let s = "hello".to_string();
s.push_str(" world");
s.push('!');
let s = format!("{}-{}", "hello", "world");
// 遍历
for c in "hello".chars() {}
for b in "hello".bytes() {}
HashMap
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);
let team_name = String::from("Blue");
let score = scores.get(&team_name); // Option<&V>
for (key, value) in &scores {
println!("{}: {}", key, value);
}
// 只在键不存在时插入
scores.entry(String::from("Blue")).or_insert(50);
并发
use std::thread;
use std::sync::mpsc;
use std::sync::{Mutex, Arc};
// 创建线程
let handle = thread::spawn(|| {
println!("hello from thread");
});
handle.join().unwrap();
// 消息传递
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
tx.send(String::from("hi")).unwrap();
});
let received = rx.recv().unwrap();
// 共享状态
let counter = Arc::new(Mutex::new(0));
let counter = Arc::clone(&counter);
thread::spawn(move || {
let mut num = counter.lock().unwrap();
*num += 1;
});
Cargo 常用命令
cargo new project_name # 创建新项目
cargo build # 构建
cargo build --release # 发布构建
cargo run # 运行
cargo test # 测试
cargo doc # 生成文档
cargo fmt # 格式化代码
cargo clippy # 代码检查
cargo add package_name # 添加依赖
cargo update # 更新依赖
常见类型转换
// 数值转换
let a: i32 = 5;
let b: i64 = a as i64;
// 字符串转数字
let num: i32 = "42".parse().unwrap();
let num: i32 = "42".parse::<i32>().unwrap();
// 数字转字符串
let s = 42.to_string();
let s = format!("{}", 42);
// 数组/切片转 Vec
let v: Vec<i32> = [1, 2, 3].to_vec();
let v: Vec<i32> = (1..=3).collect();
// Vec 转数组
let arr: [i32; 3] = v.try_into().unwrap();