fn main() {
println!("Hello, AwesomeProgram!");
}
例子 | 解释 |
struct S {} | 使用命名字段定义一个 结构体 |
struct S { x: T } | x 使用类型 T 的命名字段定义结构体 |
struct S (T); | 定义带有编号字段类型的"元组"结构体 |
struct S; | 定义 零大小 的单元结构体,不占空间 |
enum E {} | 定义一个 枚举 |
enum E { A, B(), C {} } | 定义枚举的变体,可以是 unit-A , tuple-B() 和struct-like C{} |
enum E { A = 1 } | 如果变体只是与单元类似,则允许赋值,例如 FFI |
union U {} | 用于兼容 FFI 的,类似 C union 的 unsafe 代码 |
static X: T = T(); | 具有生命周期,单独内存位置的 全局变量 |
const X: T = T(); | 定义 常量,使用时会复制到临时文件中 |
let x: T; | 在绑定为 x 的堆栈上分配 T 类型的字节,可赋值一次,不可变 |
let mut x: T; | 同上,但允许 可变 和可变借用 |
x = y; | 移动 y 到 x ,如果 T 没有实现 Copy,则 y 的所有权会失效,否则会保留所有权并把 y 复制一份 |
例子 | 解释 |
S { x: y } | 创建 struct S {} 或者 use 库 enum E::S {} ,将字段 x 设置为 y |
S { x } | 同上,但使用本地变量 x 设置字段 x |
S { ..s } | 填写剩余的字段 s ,特别是与 Default 一起使用 |
S { 0: x } | 像下一行 S(x) 一样,但设置字段 .0 使用结构体语法 |
S (x) | 创建 struct S (T) 或者 use 库 enum E::S () ,将字段 .0 设置为 x |
S | 如果 S 是单元结构体 S ,或者 use 库 enum E::S , 去创建 S 的值 |
E::C { x: y } | 创建枚举变体 C ,上面其它的方法也可以 |
() | 空元组,包括字面值和类型,又名单元 unit |
(x) | 带括号的表达式 |
(x,) | 单元素 元组 表达式 |
(S,) | 单元素元组类型 |
[S] | 未指定长度的 数组类型,即 slice,不能存储于栈中 |
[S; n] | 数组类型,固定长度是 n ,存储元素的类型是 S |
[x; n] | 具有 x 的 n 个副本的数组实例 |
[x, y] | 具有给定元素 x 和 y 的数组实例 |
x[0] | 集合索引, 使用 usize 类型, 可以用 Index, IndexMut 来实现 |
x[..] | 同上,全范围,还有 x[a..b], x[a..=b], ... 以及如下等等 |
a..b | 左闭右开范围,如 1..3 意味着 1, 2 |
..b | 从起点开始的左闭右开范围 |
..=b | 从起点开始的,包含最右边元素的范围 |
a..=b | 包容最右边元素的范围,1..=3 意味着 1, 2, 3 |
a.. | 从 a 开始到结尾的范围 |
.. | 全范围,通常意味着整个集合 |
s.x | 命名字段的访问,如果 x 不是类型 S 的一部分,则可能会尝试去调用 Deref(取消引用) |
s.0 | 编号字段访问,用于元组类型 S (T) |
- 授权未拥有内存的访问权限,另外可参阅泛型和约束部分
例子 | 解释 |
&S | 共享的引用(空间中可存放任何的 &s ) |
&[S] | 包含地址和长度的指定切片引用 |
&str | 包含地址和长度的指定字符串切片引用 |
&mut S | 可变的独占引用(也包括 &mut [S] ,&mut dyn S , …) |
&dyn T | 包含地址和 vtable 的指定 trait object 引用 |
&s | 共享的借用(如 地址,长度,vtable,...以及像 0x1234 ) |
&mut s | 可变的独占借用 |
*const S | 不可变 原生指针类型,无内存安全保证 |
&mut s | 可变 原生指针类型,无内存安全保证 |
&raw const s | 创建不经过引用的原生指针,ptr:addr_of!() |
&raw mut s | 同上,是可变的,并且需要对未对齐的字段进行补齐 |
ref s | 通过引用绑定,成为绑定引用类型 |
let ref r = s; | 等价于 let r = &s |
let S { ref mut x } = s; | 可变引用绑定,等价于 let x = &mut s.x ;简洁的解构写法见模式匹配 |
*r | 解除一个引用 r 去访问它所指向的内容 |
*r = s; | 如果 r 是可变引用,则移动或复制 s 到目标内存 |
s = *r; | 如果 *r 是 Copy 的话,使 s 等于任何 r 引用的副本 |
s = *r; | 如果 *r 不是 Copy 的话,将不起作用,且会移动并留下空赋值 |
s = *my_box; | Box 的特殊例子,如果 *my_box 不是 Copy 的话,将会移出 Box 里的内容 |
'a | 生命周期的参数符号,表示在静态分析中的存活时间 |
&'a S | 只接受存有 S 类型的地址,存在 'a 或更长 |
&'a mut S | 同上,但是 S 类型地址的内容可变 |
struct S<'a> {} | 表示 S 包含生命周期 'a 的地址, S 的创建者决定生命周期 'a 的长短 |
trait T<'a> {} | 表示 impl T for S , S 可能会包含地址 |
fn f<'a>(t: &'a T) | 同上,对于一个函数,调用者决定生命周期 'a 的长短 |
'static | 持续整个程序执行期间的固定生命周期 |
例子 | 解释 |
trait T {} | 定义一个可以实现的通用行为,特征 |
trait T : R {} | T 是 supertrait R 的 subtrait,任何 S 必须在它 impl T 之前 impl R |
impl S {} | 类型 S 的方法实现 |
impl T for S {} | 为类型 S 实现特征 T 中的方法 |
impl !T for S {} | 禁用自动派生 auto trait |
fn f() {} | 定义一个 函数,或者一个 关联函数(在 impl 内) |
fn f() -> S {} | 同上,返回类型 S 的值 |
fn f(&self) {} | 定义一个 方法,如在 impl S {} 内 |
struct S (T); | 可以定义一个 构造函数 fn S(x: T) -> S |
const fn f() {} | 在编译时可用的常量 fn ,如 const X: u32 = f(Y) |
async fn f() {} | 异步函数转换,使 f 返回一个 impl Future |
async fn f() -> S {} | 同上,但使 f 返回一个 impl Future<Output=S> |
async { x } | 在一个函数内使用,使 { x } 为 impl Future<Output=X> |
fn() -> S | 函数指针,内存持有可调用的地址 |
Fn() -> S | Callable Trait (也可以是 FnMut ,FnOnce ),由闭包实现 |
|| {} | 可借用其 捕获 的 闭包 (如,局部变量) |
|x| {} | 闭包接受一个名为 x 的参数,主体是块表达式 |
|x| x + x | 同上,没有块表达式,只有一单个表达式 |
move |x| x + y | 闭包获取其捕获的所有权,即 y 转移到闭包中 |
return || true | 闭包看起来像是 logical ORs (返回一个闭包) |
unsafe | 如果你喜欢放假前调试代码(代码的安全由你自己保证),unsafe code |
unsafe fn f() {} | 会调用导致不安全的代码块,你必须检查必要条件 |
unsafe trait T {} | 不仔细的 T 实现可能会造成不安全的代码块,实现者必须仔细检查 |
unsafe { f(); } | 向编译器保证已经检查了必要条件 |
unsafe impl T for S {} | 保证 S 是表现良好的,可以安全在 S 上使用 T |
例子 | 解释 |
while x {} | Loop,当表达式 x 是真时一直运行 |
loop {} | Loop indefinitely 直到 break ,可以主动创建 break x |
for x in iter {} | 循环遍历 迭代器 的语法糖 |
if x {} else {} | 如果表达式为真,则执行 条件分支 |
'label: loop {} | 循环标签,用于嵌套循环中的流程控制 |
break | Break expression 可退出循环 |
break x | 同上,但使 x 为循环表达式的值(仅在实际的 loop ) |
break 'label | 不仅要退出这个循环,还要退出标有 'label 的封闭循环 |
break 'label x | 同上,但使 x 为标有 'label 的封闭循环的值 |
continue | Continue expression 跳转到此循环后的下一个循环迭代 |
continue 'label | 同上,但使标有 'label 的封闭循环替代本次循环 |
x? | 如果 x 是 Err 或 None ,return and propagate |
x.await | 只作用于 async 里,直到 Future 生成流或准备好 x |
return x | 从函数中提前返回,更惯用的做法是在结尾使用表达式 |
f() | 调用 f ,(如一个函数,闭包,函数指针, Fn ) |
x.f() | 调用成员函数,需要 f 把 self , &self ,...作为第一个参数 |
X::f(x) | 同 x.f() ,除非实现了 impl Copy for X {} ,否则 f 仅可被调用一次 |
X::f(&x) | 同 x.f() |
X::f(&mut x) | 同 x.f() |
S::f(&x) | 如果 x derefs 到 S 同 x.f() 一样, 即 x.f() 发现了 S 的方法 |
T::f(&x) | 如果 x impl T 同 x.f() 一样, 即 x.f() 在范围内发现了 T 的方法 |
X::f() | 调用关联函数,如 X::new() |
<X as T>::f() | 为 X 调用特征方法 T::f() 的实现 |
例子 | 解释 |
mod m {} | 定义一个模块,从 {} 内部获取定义 |
mod m; | 定义一个模块,从 m.rs 或 m/mod.rs 中获取定义 |
a::b | 在 a (mod , enum , …) 的内部,名命空间的路径到元素 b |
::b | 在 crate root、external prelude、global path 搜索 b |
crate::b | 在 crate root 中搜索 b |
self::b | 在当前的模块中搜索 b |
super::b | 在上一级模块中搜索 b |
use a::b; | 在范围内直接使用 b 而不需要 a 其余部分 |
use a::{b, c}; | 同上,但是会把 b 和 c 放到范围内 |
use a::b as x; | 把 b 放到范围,使用别名 x ,也像这样 use std::error::Error as E |
use a::b as _; | 把 b 作为匿名放到范围中,通常适用于命名冲突的特征 |
use a::*; | 把 a 内的所有接口放到范围中,仅推荐如果 a 是一些 prelude |
pub use a::b; | 把 a::b 放到范围中,并且在这里重新导出 |
pub T | 如果上一级路径是可见的则公开 visibility |
pub(crate) T | 最多在当前 crate 中可见 |
pub(super) T | 最多在上一级中可见 |
pub(self) T | 最多在当前模块中可见(默认和没有 pub 一样). |
pub(in a::b) T | 最多在 a::b 中可见 |
extern crate a; | 声明对外部的 crate 依赖,仅在 use a::b 内 |
extern "C" {} | 从 FFI 声明外部依赖项和 ABI(如 "C") |
extern "C" fn f() {} | 定义要使用 ABI("C")导出到 FFI 的函数 |
- 子模块中的项目始终可以访问任何项目,无论是否为
pub
- 类型的简写名称,以及将一种类型转换为另一种类型的方法
例子 | 解释 |
type T = S; | 创建一个类型别名,即 S 的另一个名称 |
Self | implementing type,如 fn new() -> Self |
self | 在 fn f(self) {} 里的方法,与 fn f(self: Self) {} 一样 |
&self | 同上,但将 self 改为借用,与 f(self: &Self) 一样 |
&mut self | 同上,但将 self 改为可变借用,与 f(self: &mut Self) 一样 |
self: Box<Self> | 任意self类型 Arbitrary self type,给智能指针添加方法(my_box.f_of_self() ) |
S as T | 消除类型 S 改为特征 T , 如 <S as T>::f() |
S as R | 在use符号中使用,导入 S 作为 R ,如 use a::S as R |
x as u32 | 简单映射,可能会遭到意外的截断 |
例子 | 解释 |
m!() | 宏调用, 也可以 m!{} , m![] (依赖宏的实现) |
#[attr] | 外部属性,用于注释下面的条目 |
#![attr] | 内部属性,用于注释上一级和周围的条目 |
内部宏 | 解释 |
$x:ty | 宏捕获,:... 片段为 $x 声明了允许的内容 |
$x | 宏替换,例如使用上面捕获的 $x:ty |
$(x),* | 宏重复,例如在宏中重复零次或多次 |
$(x),? | 同上,但重复零次或一次 |
$(x),+ | 同上,但重复一次或多次 |
$(x)<<+ | 实际上除了分隔符 , 也可以接受这样的 << |
- 在 match 或 let 表达式 以及函数参数中的模式构造
例子 | 解释 |
match m {} | 初始化模式匹配,然后使用匹配分支 |
let S(x) = get(); | 明显地,let 还可以解构成类似下面的形式 |
let S { x } = s; | 仅把 x 绑定到 s.x 的值 |
let (_, b, _) = abc; | 仅把 b 绑定到 abc.1 的值 |
let (a, ..) = abc; | 忽略 其余部分 也有作用 |
let (.., a, b) = (1, 2); | 指定绑定优先于 其余部分,这里 a 是 1 ,b 是 2 |
let s @ S { x } = get(); | 当 x 绑定到 s.x 时,s 绑定到 S ,pattern binding |
let w @ t @ f = get(); | 给每个 w t f 存储 get() 的三个副本结果 |
let Some(x) = get(); | 如果是可辩驳模式不会起到作用,应使 if let 来代替 |
if let Some(x) = get() {} | 如果模式可被分配成分支(如,枚举变体),语法糖 |
while let Some(x) = get() {} | 同上,{} 只要模式可被分配成分支,将继续调用 get() |
fn f(S { x }: S) | 函数参数也像 let 一样使用,这里把 x 绑定到 f(s) 的 s.x |
*脱糖后如 match get() { Some(x) => {}, _ => () }
- 匹配表达式中的模式匹配分支,左侧这些分支也可以在 let 表达式中找到
在匹配分支内 | 解释 |
E::A => {} | 匹配枚举变体 A ,模式匹配 |
E::B ( .. ) => {} | 匹配枚举元组变体 B ,任何索引的通配符 |
E::C { .. } => {} | 匹配枚举结构体变体,任何字段的通配符 |
S { x: 0, y: 1 } => {} | 匹配结构体与指定值(仅接受 s 与 s.x 0 和 s.y 1 ) |
S { x: a, y: b } => {} | 匹配结构体与 any(!) ,并且绑定 s.x 到 a 和 s.y 到 b |
S { x, y } => {} | 同上,但分别地把 s.x 和 s.y 的简写 x 和 y 作为绑定 |
S { .. } => {} | 将 struct 与任何值匹配 |
D => {} | 如果 D 在 use 中,匹配枚举变体到 E::D |
D => {} | 如果 D 不在 use 中,匹配任何东西绑定到 D ,也可能是 E::D 的一种错误形式 |
_ => {} | 匹配任何内容(所有其余部分)的完全通配符。 |
0 | 1 => {} | 模式选择,or-patterns |
E::A | E::Z => {} | 同上,但是在枚举变体上 |
E::C {x} | E::D {x} => {} | 同上,但如果所有变体都有它,则绑定 x |
Some(A | B) => {} | 同上,可以匹配深度嵌套的 or-patterns |
(a, 0) => {} | 为 a 和 0 匹配任何值的元组 |
[a, 0] => {} | 切片模式,为 a 和 0 匹配任何值的数组 |
[1, ..] => {} | 子切片模式,匹配数组从 1 开始,任何其余的值 |
[1, .., 5] => {} | 匹配数组从 1 开始到 5 结束中的值 |
[1, x @ .., 5] => {} | 同上,但还会绑定 x 到代表中间的切片 |
[a, x @ .., b] => {} | 同上,但分别匹配任意的第一个和最后一个,绑定为 a 和 b |
1 .. 3 => {} | 范围模式,这里会匹配 1 和 2 ,部分不稳定 |
1 ..= 3 => {} | 包含范围模式,匹配 1 ,2 和 3 |
1 .. => {} | 开放的范围模式,匹配 1 和任何更大的数 |
x @ 1..=5 => {} | 绑定匹配到 x ,模式绑定,此处的 x 将是 1 ,2 ,... 或 5 |
Err(x @ Error {..}) => {} | 也可以用于嵌套,这里 x 绑定到 Error ,特别是下面有用的 if 形式 |
S { x } if x > 10 => {} | 模式 匹配保护,条件也必须为真才能匹配 |
- 泛型结合类型构造函数,特征和函数为你的代码提供更大的灵活性
例子 | 解释 |
S<T> | 带有类型参数的 泛型 类型(T 表示占位符名称) |
S<T: R> | 打印简写的 trait bound 范式(R 必须是实际的特征) |
T: R, P: S | Independent trait bounds(这里一个给 T ,一个给 P ) |
T: R, S | 编译报错,你可能希望像使用下面的用法 R + S |
T: R + S | Compound trait bound, T 必须满足 R 和 S |
T: R + 'a | 同上,但是 T 必须满足 R ,如果 T 有生命周期,必须比 'a 更久 |
T: ?Sized | 选择离开预定义的 trait bound,这里是 Sized |
T: 'a | 类型的 lifetime bound,如果 T 存在引用,则必须比 'a 更久 |
T: 'static | 同上,特别是不意味着 T 将会 'static ,仅可以会 'static |
'b: 'a | 'b 的生命周期必须存活至少为 'a |
S<const N: usize> | Generic const bound,类型 S 的使用者可以提供常量值 N |
S<10> | 在使用时,常量边界可以作为原始值提供 |
S<{5+5}> | 表达式必须放在大括号中 |
S<T> where T: R | 几乎和 S<T: R> 一样,但语法越长越易于阅读 |
S<T> where u8: R<T> | 允许创建生成其它类型的条件语句 |
S<T = R> | Default parameters,更容易使用,但也很灵活 |
S<const N: u8 = 0> | 默认参数是常量,如 f(x: S) {} 中参数 N 是 0 |
S<T = u8> | 默认参数是类型,如 f(x: S) {} 中参数 T 是 u8 |
S<'_> | anonymous lifetime,如果可以明显的看出来,会要求编译器推断出来 |
S<_> | anonymous type,如 let x: Vec<_> = iter.collect() 一样 |
S::<T> | Turbofish 会调用类型消除歧义,如 f::<u32>() 一样 |
trait T<X> {} | 基于 X 之上的一个特征泛型,可以有多个 impl T for S (一对 X ) |
trait T { type X; } | 定义 关联类型 X ,仅 impl T for S 的一种可能 |
type X = R; | 在 impl T for S { type X = R; } 中设置关联类型 |
impl<T> S<T> {} | 为在 S<T> 中任意的 T 实现功能,T 是类型参数 |
impl S<T> {} | 完全为 S<T> 实现功能,T 是指定类型(如 S<u32> ) |
fn f() -> impl T | Existential types,返回一个 impl T 的未知调用者 S |
fn f(x: &impl T) | Trait bound impl traits, 类似于 fn f<S:T>(x: &S) |
fn f(x: &dyn T) | dynamic dispatch 的标记,f 不会被单态化(monomorphized) |
fn f() where Self: R; | 在 trait T {} 中,使 f 仅可访问 impl R 的已知类型 |
fn f() where Self: Sized; | 使用 Sized 可以从 dyn T trait object vtable 中选出 f ,启用 trait object |
fn f() where Self: R {} | 其它 R 有用的 w. dflt ,方法(non dflt 无论怎样都需要被实现) |
例子 | 解释 |
for<'a> | higher-ranked bounds 的标记 |
trait T: for<'a> R<'a> {} | 任何 impl T 的 S 都必须为了整个生命周期满足 R |
fn(&'a u8) | 函数指针类型持有 fn 可调用的指定的生命周期 |
for<'a> fn(&'a u8) | Higher-ranked type 持有 fn 可调用的任何上面的子类型 |
fn(&'_ u8) | 同上,自动展开到类型 for<'a> fn(&'a u8) |
fn(&u8) | 同上,自动展开到类型 for<'a> fn(&'a u8) |
dyn for<'a> Fn(&'a u8) | Higher-ranked(trait-object)类型,像上面的 fn 一样 |
dyn Fn(&'_ u8) | 同上,自动展开到类型 dyn for<'a> Fn(&'a u8) |
dyn Fn(&u8) | 同上,自动展开到类型 dyn for<'a> Fn(&'a u8) |
* for<>
是类型的一种,下面展示了 impl T for for<'a> fn(&'a u8)
这样的写法
实现特征 | 解释 |
impl<'a> T for fn(&'a u8) {} | 对于指针 fn ,其中调用接受指定的 'a , imple trait T |
impl T for for<'a> fn(&'a u8) {} | 对于指针 fn ,其中调用接受任何的 imple trait T |
impl T for fn(&u8) {} | 同上,简写版 |
例子 | 解释 |
"..." | 字符串文本,UTF-8 将解释 \n 为换行符 |
r"..." | 原始字符串文本,UTF-8 不会解释 \n |
r#"..."# | 原始字符串文本,UTF-8 也可以包含 " ,# 数量是可变的 |
b"..." | 字节字符串文本,构造 ASCII [u8] ,不是字符串 |
br"...", br#"..."# | 原始字节字符串文本,ASCII [u8] ,以上的组合 |
'🦀' | 字符文本,固定 4 字节的 unicode char |
b'x' | ASCII 字节文本 |
例子 | 解释 |
/// | 外部文档注释,通常用于类型、特征、函数 |
//! | 内行文档注释,主要用于文件到文档模块的开头 |
// | 行注释,使用这些来记录代码流或内部结构 |
/*...*/ | 块注释 |
/**...*/ | 外部块文档注释 |
/*!...*/ | 内部块文档注释 |
例子 | 解释 |
! | 始终为空 |
_ | 未命名的通配符变量绑定,例如 |x, _| {} |
let _ = x; | 未命名的分配是不执行的,不会 move out x 或保留目标值 |
_x | 变量绑定明确标记为未使用 |
1_234_567 | 用于可清晰分辨的数字分隔符 |
1_u8 | 数字文本 的类型说明符(还可以是 i8 ,u16 …) |
0xBEEF, 0o777, 0b1001 | 十六进制(0x )、八进制(0o )和二进(0b )的整数文本 |
r#foo | 用于版本兼容的原始标识符 |
x; | 语句终止符或表达式 |
Rust 支持大多数运算符(+
,*
,%
,=
,==
,...),包括重载。因为它们在 Rust 中的行为没有什么不同,所以就不在此处列出它们。