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 | 代码块 | { ... } |
item | 项 | fn 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
} )*
}
};
}