跳到主要内容

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;
});

Rust 2024 新特性速查

异步闭包

// 异步闭包基本语法
let async_closure = async |x: i32| {
tokio::time::sleep(Duration::from_millis(100)).await;
x * 2
};
let result = async_closure(5).await;

// 可以捕获环境变量
let mut counter = 0;
let increment = async || {
counter += 1;
counter
};
let n = increment.await; // 1

// AsyncFn trait(已在 prelude)
fn process<F>(f: F) -> impl Future<Output = i32>
where F: AsyncFn(i32) -> i32
{
async move { f(42).await }
}

RPIT 生命周期捕获

// Rust 2024: impl Trait 默认捕获所有作用域内的泛型参数
fn f<'a, T>(x: &'a (), y: T) -> impl Sized {
// 等价于 impl Sized + use<'a, T>
(x, y)
}

// 使用 use<..> 显式指定捕获
fn g<'a, T>(x: &'a (), y: T) -> impl Sized + use<T> {
// 只捕获 T,不捕获 'a
y
}

// 不捕获任何参数
fn h<'a, T>(x: &'a (), y: T) -> impl Sized + use<> {
// 返回类型不依赖任何泛型参数
42
}

Prelude 变更

// Rust 2024: Future 和 IntoFuture 自动导入
// 无需显式 use std::future::Future

async fn example() {
// Future trait 直接可用
let fut = async { 42 };
let result = fut.await;
}

其他 Rust 2024 变更

// std::env 函数现在是 unsafe
// unsafe { std::env::set_var("KEY", "value"); }
// unsafe { std::env::remove_var("KEY"); }

// Box<[T]> 实现 IntoIterator
let boxed: Box<[i32]> = Box::new([1, 2, 3]);
for item in boxed {
println!("{}", item);
}

// 元组支持 FromIterator 和 Extend(最多 12 元素)
let (evens, odds): (Vec<_>, Vec<_>) = (0..10).partition(|&x| x % 2 == 0);

Unsafe Rust

五种 Unsafe 超能力

// 1. 解引用原始指针
let mut num = 5;
let r1 = &num as *const i32;
let r2 = &mut num as *mut i32;
unsafe {
println!("r1: {}", *r1);
println!("r2: {}", *r2);
}

// 2. 调用 unsafe 函数
unsafe fn dangerous() {}
unsafe { dangerous(); }

// 3. 访问可变静态变量
static mut COUNTER: u32 = 0;
unsafe { COUNTER += 1; }

// 4. 实现 unsafe trait
unsafe trait Foo {}
unsafe impl Foo for i32 {}

// 5. 访问 union 字段
union IntOrFloat { i: i32, f: f32 }
let u = IntOrFloat { i: 42 };
unsafe { println!("{}", u.i); }

原始指针

// 创建原始指针
let r1 = &num as *const i32; // 从引用转换
let r2 = &raw const num; // Rust 2021+ 原始借用
let r3 = 0x1234 as *const i32; // 从地址创建

// 解引用(需要 unsafe)
unsafe { *r1; }

// 指针方法
ptr.add(1); // 偏移(unsafe)
ptr.offset(1); // 偏移(unsafe)
ptr.read(); // 读取(unsafe)
ptr.write(val); // 写入(unsafe)
ptr.is_null(); // 检查是否为空(safe)

FFI(Rust 2024 Edition)

// Rust 2024+: extern 块必须使用 unsafe
unsafe extern "C" {
fn abs(input: i32) -> i32;
}
unsafe { abs(-3); }

// 导出 Rust 函数给 C(Rust 2024+)
#[unsafe(no_mangle)]
pub extern "C" fn call_from_c() {
println!("Hello from Rust!");
}

// Rust 2024 之前
// #[no_mangle]
// pub extern "C" fn call_from_c() { ... }

Rust 2024 Unsafe 变更速查

// 1. unsafe extern 块(必须)
unsafe extern "C" { fn foo(); }

// 2. unsafe 属性(必须)
#[unsafe(export_name = "my_func")]
#[unsafe(no_mangle)]
#[unsafe(link_section = ".my_section")]

// 3. 禁止 static mut 引用
static mut DATA: i32 = 0;
// let ref_data = unsafe { &DATA }; // Rust 2024: 编译错误!
// let ref_mut = unsafe { &mut DATA }; // Rust 2024: 编译错误!

// 正确做法:使用原始指针
let ptr = unsafe { std::ptr::addr_of!(DATA) };
let ptr_mut = unsafe { std::ptr::addr_of_mut!(DATA) };

// 4. unsafe fn 内的 unsafe 操作需要显式 unsafe 块
unsafe fn my_unsafe_fn(ptr: *const i32) -> i32 {
unsafe { *ptr } // Rust 2024+: 必须显式 unsafe 块
}

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 # 更新依赖
cargo +nightly miri test # 使用 Miri 检测 UB

常见类型转换

// 数值转换
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();

let-else 模式

// 基本用法:匹配失败时提前返回
let Some(value) = option else {
return;
};

// 处理 Result
let Ok(data) = result else {
eprintln!("操作失败");
return;
};

// 解构枚举
let Message::Move { x, y } = msg else {
println!("不是移动消息");
return;
};

// 在循环中使用
for item in items {
let Some(value) = item else {
continue; // 跳过 None
};
// 处理 value
}

常用 Trait 快速实现

Debug 和 Display

use std::fmt;

#[derive(Debug)] // 自动实现
struct Point {
x: i32,
y: i32,
}

// 手动实现 Display
impl fmt::Display for Point {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "({}, {})", self.x, self.y)
}
}

From 和 Into

// 实现 From 自动获得 Into
impl From<i32> for MyType {
fn from(value: i32) -> Self {
MyType(value)
}
}

// 现在可以:
let my = MyType::from(42);
let my: MyType = 42.into(); // 自动实现

Default

#[derive(Default)]
struct Config {
timeout: u32, // 默认 0
retries: u32, // 默认 0
debug: bool, // 默认 false
}

// 使用
let config = Config::default();
let config = Config {
timeout: 60,
..Default::default() // 其他字段使用默认值
};

Error 类型

use std::fmt;
use std::error::Error;

#[derive(Debug)]
struct MyError {
message: String,
}

impl fmt::Display for MyError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.message)
}
}

impl Error for MyError {}

调试技巧

dbg! 宏

// 快速调试输出(输出到 stderr)
let x = 5;
dbg!(x); // 输出: [src/main.rs:2] x = 5
dbg!(x + 1); // 输出: [src/main.rs:3] x + 1 = 6
let y = dbg!(x * 2); // 返回值可以继续使用
println!("y = {}", y); // y = 10

// 调试表达式
let result = dbg!(some_function());

断言宏

// debug_assert 只在 debug 模式生效
debug_assert!(x > 0);
debug_assert_eq!(a, b);
debug_assert_ne!(a, b);

// assert 在所有模式生效
assert!(x > 0);
assert_eq!(a, b, "a 应该等于 b");
assert_ne!(a, b);

编译时检查

// 确保类型实现了某个 trait
fn ensure_debug<T: Debug>(_: &T) {}

// 编译时大小检查
const _: () = assert!(std::mem::size_of::<usize>() == 8);

迭代器常用操作速查

let v = vec![1, 2, 3, 4, 5];

// 转换
v.iter().map(|x| x * 2); // [2, 4, 6, 8, 10]
v.iter().filter(|x| *x % 2 == 0); // [2, 4]

// 查找
v.iter().find(|x| **x > 3); // Some(&4)
v.iter().position(|x| *x == 3); // Some(2)
v.iter().any(|x| *x > 5); // false
v.iter().all(|x| *x > 0); // true

// 聚合
v.iter().sum::<i32>(); // 15
v.iter().product::<i32>(); // 120
v.iter().max(); // Some(&5)
v.iter().min(); // Some(&1)

// 折叠
v.iter().fold(0, |acc, x| acc + x); // 15

// 收集
v.iter().collect::<Vec<_>>(); // Vec<&i32>
v.iter().cloned().collect::<Vec<_>>(); // Vec<i32>

// 排序
let mut v = vec![3, 1, 4, 1, 5];
v.sort(); // [1, 1, 3, 4, 5]
v.sort_by(|a, b| b.cmp(a)); // 降序
v.dedup(); // 去重 [1, 3, 4, 5]

// 分组
let (even, odd): (Vec<_>, Vec<_>) = v.iter().partition(|x| *x % 2 == 0);

// 链式操作
let result: i32 = (1..=10)
.filter(|x| x % 2 == 0) // 2, 4, 6, 8, 10
.map(|x| x * x) // 4, 16, 36, 64, 100
.sum(); // 220

字符串处理速查

let s = "  Hello, World!  ";

// 修剪
s.trim(); // "Hello, World!"
s.trim_start(); // "Hello, World! "
s.trim_end(); // " Hello, World!"

// 分割
s.split_whitespace(); // ["Hello,", "World!"]
s.split(','); // [" Hello", " World! "]
s.lines(); // 按行分割

// 替换
s.replace("World", "Rust"); // " Hello, Rust! "
s.replacen("l", "L", 1); // 只替换第一个

// 大小写
s.to_lowercase();
s.to_uppercase();

// 检查
s.starts_with(" He");
s.ends_with("! ");
s.contains("World");
s.is_empty();
s.len(); // 字节数
s.chars().count(); // 字符数

// 追加
let mut s = String::from("Hello");
s.push_str(", World!");
s.push('!');

Option 和 Result 快速操作

// Option 快速处理
let opt = Some(5);
opt.unwrap(); // 5,None 时 panic
opt.unwrap_or(0); // 5,None 时返回 0
opt.unwrap_or_else(|| 0); // 5,None 时调用闭包
opt.expect("必须有值"); // 带消息的 unwrap
opt.map(|x| x * 2); // Some(10)
opt.and_then(|x| Some(x * 2)); // Some(10)
opt.filter(|x| *x > 3); // Some(5)
opt.or(Some(10)); // Some(5)
opt.xor(Some(10)); // None(两个都是 Some)

// Result 快速处理
let res: Result<i32, &str> = Ok(5);
res.unwrap(); // 5,Err 时 panic
res.unwrap_or(0); // 5
res.unwrap_or_default(); // 5,Err 返回默认值
res.expect("操作失败"); // 带消息
res.map(|x| x * 2); // Ok(10)
res.map_err(|e| format!("错误: {}", e));
res.and_then(|x| Ok(x * 2)); // Ok(10)
res.or(Ok(10)); // Ok(5)
res.unwrap_err(); // Err 时返回错误值

// 转换
opt.ok_or("错误"); // Option -> Result
res.ok(); // Result -> Option
res.err(); // Result -> Option<E>

属性速查

属性语法

// 外部属性(应用于其后项)
#[attribute]
#[attribute(arg1, arg2)]
#[attribute = "value"]

// 内部属性(应用于其所在项)
#![attribute]
#![allow(unused)]

条件编译属性

// 目标平台
#[cfg(target_os = "linux")]
#[cfg(target_os = "windows")]
#[cfg(target_os = "macos")]

// 目标架构
#[cfg(target_arch = "x86_64")]
#[cfg(target_arch = "arm")]

// 条件组合
#[cfg(all(unix, target_pointer_width = "64"))]
#[cfg(any(windows, target_os = "macos"))]
#[cfg(not(debug_assertions))]

// 特性标志
#[cfg(feature = "my_feature")]

// 测试模式
#[cfg(test)]

// 条件属性
#[cfg_attr(debug_assertions, derive(Debug))]

派生属性

// 常用派生
#[derive(Debug)] // 调试输出 {:?}
#[derive(Clone)] // 克隆 .clone()
#[derive(Copy)] // 复制(需要 Clone)
#[derive(PartialEq, Eq)] // 相等比较 == !=
#[derive(PartialOrd, Ord)] // 排序 < > <= >=
#[derive(Hash)] // 哈希 HashMap/HashSet
#[derive(Default)] // 默认值

// 组合派生
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct MyStruct { }

诊断属性

#[allow(unused)]              // 允许警告
#[warn(unused)] // 警告
#[deny(unused)] // 拒绝(编译错误)
#[forbid(unsafe_code)] // 禁止(比 deny 更严格)

// 常用诊断
#[allow(unused_variables)]
#[allow(dead_code)]
#[allow(unused_imports)]
#[allow(clippy::all)]

#[deprecated(since = "1.0", note = "使用新函数")]
#[must_use = "返回值必须使用"]

测试属性

#[test]                       // 测试函数
#[test]
#[ignore] // 忽略测试
#[test]
#[should_panic] // 期望 panic
#[test]
#[should_panic(expected = "错误信息")] // 期望特定 panic

函数属性

#[inline]                     // 建议内联
#[inline(always)] // 强制内联
#[inline(never)] // 永不内联
#[cold] // 冷门函数
#[no_mangle] // 禁止命名修饰
#[export_name = "name"] // 导出名称
#[track_caller] // 追踪调用位置

模块和可见性

#[path = "custom/path.rs"]    // 自定义模块路径
#[doc(hidden)] // 隐藏文档
#[non_exhaustive] // 非穷尽类型

宏速查

声明式宏语法

macro_rules! macro_name {
// 规则:匹配器 => 转录器
($arg:expr) => {
// 使用 $arg
};

// 多分支
($a:expr, $b:expr) => { /* ... */ };
($a:expr) => { /* ... */ };
() => { /* ... */ };
}

元变量类型

分类符匹配内容示例
expr表达式1 + 2
ident标识符foo
ty类型i32
literal字面量42
stmt语句let x = 5;
pat模式Some(x)
path路径std::mem
tt标记树任意标记
block代码块{ ... }
itemfn foo() {}
vis可见性pub

重复操作符

macro_rules! repeat_demo {
// * 零次或多次
($($x:expr),*) => {
$( $x )*
};

// + 一次或多次
($($x:expr),+) => {
$( $x )+
};

// ? 零次或一次
($($x:expr)?) => {
$( $( $x )? )?
};

// 带分隔符
($($x:expr),* $(,)?) => { // 允许尾随逗号
$( $x );*
};
}

常用内置宏

// 打印
println!("hello");
println!("hello {}", name);
format!("value: {}", x);

// 调试
dbg!(x); // 输出到 stderr

// 字符串化
stringify!(expr); // "expr"

// 环境变量
env!("PATH"); // 编译时获取
option_env!("VAR"); // Option<&str>

// 文件和行号
file!(); // 文件名
line!(); // 行号
column!(); // 列号

// 包含
include!("file.rs"); // 包含文件
include_str!("file.txt"); // 包含字符串
include_bytes!("file.bin"); // 包含字节

// 编译时检查
assert!(condition); // 编译时断言
const _: () = assert!(SIZE > 0);

// 汇编(高级)
// std::arch::asm!(...);

宏定义示例

// 简单宏
macro_rules! say_hello {
() => { println!("Hello!"); };
}

// 带参数
macro_rules! print_value {
($val:expr) => { println!("{}", $val); };
}

// 创建向量
macro_rules! my_vec {
($($x:expr),*) => {
{
let mut v = Vec::new();
$( v.push($x); )*
v
}
};
}

// 结构体构建器
macro_rules! builder {
($name:ident { $($field:ident: $type:ty),* }) => {
struct $name { $($field: $type),* }
impl $name {
fn new() -> Self {
Self { $($field: Default::default()),* }
}
$( fn $field(mut self, v: $type) -> Self {
self.$field = v;
self
} )*
}
};
}