Fork me on GitHub

rust 语法小册子

Rust语法速查小册

1. 数据结构

通过关键字定义的数据类型和内存位置

  • struct S{}定义一个命名成员的结构体
    • struct S {x:T} 定义一个结构体,成员名为x,成员类型为T
    • struct S(T) 定义元组类型结构体,成员.0类型为T
    • struct S 定义零长单元结构体,不占空间哦
  • enum E{} 定义一个枚举类,
    • enum E{A, B(), C{} }定义各种类型枚举,可以是单元A,元组B,或者结构C
    • enum E {A=1} 如果变量只是单元,允许赋值,如FFI使用
  • union U{} unsafe 类C联合体,为了FFI兼容
  • static X: T = T();'static声明周期的全局变量,单一内存位置
  • const X : T = T();定义常量
  • let x: T;定义栈T bytes。一次分配,不可变
  • let mut x:T; 允许可变的和可变借用
    • x = y; 移动y到x,如果T类型没有实现Copy,那么y将变为不可用,如果实现了Copy,那么将y拷贝给x。

创建和获取结构体数据,可一些siglic类型

  • S {x:y} 创建struct S{}enum E::S{}设置y给成员x
  • S {x} 用局部变量x直接赋值
  • S {..s} 将其余变量设置为s的
  • S {0:x} 类似S(x) 设置.0成员值
  • S(x) 创建S(T)或者enum E::S()
  • S如果S为单元struct S;或者enum E::S
  • E::C {x:y}类似
  • ()空元组,即使文本又是类型,(x)括号表达式,(x,)元组单个元素,(S,)元组单个元素
  • [S]未定义长度的数组类型,如切片,不能在栈上定义。
  • [S; n] 定长数组,长度为n,元素类型为S
  • [x; n] 数组实例,长度为n,每个元素都是x
  • [x, y] 数组元素,值为x,y
  • x[0] 集合索引,实现了Index, IndexMut的trait
    • x[..]所有元素,给个范围
  • a..b给了范围[a, b)
  • ..b``(-∞,b),..=b``(-∞,b]

2.引用和指针

不属于自己所有内存授权

  • &S共享引用,空间可以被任何&s所有
    • &[S] 切片的引用,包含了地址和长度
    • &str string切边的引用,包含地址和长度
    • &mut S 允许可变的引用,唯一性(&mut [S], &mut dyn S)
    • &dyn T trait object引用,包含地址和vtable
  • &s共享借用
    • &mut s排它借用允许改变
  • *const S不可变裸指针w/o内存安全
    • *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 = s;如果r是可变的引用,move或者copys给目标内存
    • s = *r;如果r实现了Copy,则将*r复制给s,如果*r没实现Copy将会move
    • s = *my_box如果没实现了Copy则也会move
  • 'a在静态分析一个流程的一个声明周期参数
    • &'a S只接受持有s的地址,这个地址存在'a或更长
    • &'a mut S一样,只是可变
    • struct S<'a> {}通知S将会包含声明周期'a地址。S创建来决定'a
    • trait T<'a>{}
    • fn f<'a>(t: &'a T)
  • 'static静态声明周期

3.函数和行为

定义代码单元和他们抽象

  • trait T {}
  • trait T: R {} T是supertraitR的subtrait。任何S必须在实现T之前先实现R
  • impl S{}方法
  • impl T for S {}实现类型S的T
  • impl !T for S {} 关闭autotrait
  • fn f() {}
    • fn f() -> S{}
    • fn f(&self) {}
  • struct S(T);
  • const fn f() {} 编译时常量函数const X:u32 = f(Y)
  • async fn f() {}异步函数
    • async fn () -> S{}
    • async {x}
  • fn() -> S 函数指针
  • Fn() -> S 可调用的闭包FnMut, FnOnce
  • ||{}
    • |x|{}
    • |x|x+x
    • move |x| x + y闭包获得捕获的所有权,y转移到了闭包
    • return ||true 返回一个闭包
  • unsafe
    • unsafe fn f() {}
    • unsafe trait T {}
    • unsafe { f();}
    • unsafe impl T for S {}

4.控制流

  • while x {}
  • loop {}
  • for x in inter {}
  • if x {} else {}
  • 'label: loop {}
  • break
  • break x x作为表达式值,loop中使用
  • break 'label 或者break 'label x
  • continuecontinue 'label
  • x?如果x式Err或者None则返回
  • x.await async使用
  • return x 函数中的先返回
  • x.f()
    • X::f()
    • X::f(&x)
    • X::f(&mut x)
  • X::f()
    • <X as T>::f() 调用trait T::f()方法

5.代码结构

  • mod m {}
  • mod m;定义一个模块,从m.rsm/mod.rs中获取
  • a::b
    • ::b搜索crate root或external prelude; global path
    • crate::b crate root中找b
    • self::b当前mod找b
    • super::b 父模块找b
  • use a::b; 这个范围可直接使用b
    • use a::{b, c};
    • use a::b as x;
    • use a::b as _;
    • use a::*;
    • pub use a::b;
  • pub T
    • pub(crate) T 当前crate可访问
    • pub(super) T
    • pub(self) T
    • pub(in a::b) T祖先a::b可见
  • extern crate a;依赖外部crate,可以直接使用use a::b
  • extern "C" {}依赖外部ABI
  • extern "C" fn f() {}定义可被外部访问的FFI

6.类型重命名和转换

  • type T = S;
  • Self
  • self
    • &self
    • &mut self
    • self: Box<Self>
  • S as T
  • S as R
  • x as u32

7.宏和属性

  • m!()宏调用,也可以m!{}m![]根据具体宏

  • #[attr]外部属性

  • #![attr]内部属性

  • $x:ty宏捕获,:..fragment声明$x允许的内容

  • $x宏替换,使用上面的声明内容

  • $(x),* 宏重复,零或更多

    • $(x),? 0或1
    • $(x),+, 1或更多
    • $(x)<<+ 分隔符不是,这里是<<

8.样式匹配

  • match m {}
  • let S(x) = get()
    • let S {x} = s;
    • let (_, b, _) = abc;
    • let (a, ..) = abc;
    • let (.., a, b) = (1, 2)
    • let s & S{x} = get(); 将s绑定到S,同时x绑定到是s.x
    • let w @ t @ f = get();存放3个复制get()结果,分别给w,t,f
    • let Some(x) = get() {}不能工作,使用if let
  • if let Some(x) = get() {}
  • while let Some(x) = get() {}
  • fn f(S {x} : S)函数参数也可以项let一样将s.x给f(s)

语法糖
match get() { Some(x) => {}, _ => () }

arm匹配

  • E::A => {}匹配枚举类型A
  • E::B(..) => {} 匹配枚举元组变量,忽略所有索引
  • E::C {..} => {} 匹配结构体变量C,忽略所有成员
  • S {x:0, y:1} => {} 匹配结构体(只接收s.x=0和s.y=1)
  • S {x: a, y: b} => {}匹配结构体任何结构体,绑定s.x给a,s.y给b
    • S{x, y} => {}同样,但是简写方式
  • S{..} => {}匹配结构体有任何值的
  • _ => {}匹配剩余的
  • 0 | 1 => {} 匹配可选,或者模式
    • E::A | E::Z => {}
    • E::C {x} | E::D {x} => {}
    • Some(A | B) => {}也可以多层嵌套
  • (a, 0) => {}匹配任何a和第二个是0的元组
  • [a, 0] => {}切片样式,匹配数组第一个任何为a,第二个为0
    • [1, ..] => {}
    • [1, .., 5] => {}
    • [1, x @ .., 5] => {}中间的绑定为x
    • [a, x @ .., b] => {}
  • 1 .. 3 => {}
    • 1 ..= 3 => {}
    • 1 .. => {}
  • x @ 1..=5 => {}绑定匹配给x
    Err(x @ Error {..}) => {} 嵌套绑定
  • S{x} if x > 10 => {}条件匹配,条件要为true

9.模板和约束

  • S<T>
  • S<T:R> trait bound R必须是具体的trait,T必须实现R
    • T: R, P:S
    • T: R, S这个是不对的,要写成T: R + S
    • T: R + 'a
    • T: ?Sized可选退出预定义的trait边界
    • T: 'a如果T是引用,必须长于'a
    • T: 'static
    • 'b : 'a 'b周期大于等于'a
  • S<const N: usize>常量约束
    • S<10>使用方法
    • S<{5 + 5}>表达式必须放入大括号中
  • S<T> where T: RS<T: R>相同,看起来好点
    • S<T> where u8: R<T>可以用来条件称述
  • S<T = R> 默认参数
    • S<const N: u8 = 0>
    • S<T = u8>
  • S<'_>推断匿名声明周期,如果明显的让编译器计算出
  • S<_>推断匿名类型let x: Vec<_> = iter.collect()
  • S::<T>调用地方消除歧义f::<u32>()
  • trait T<X> {}可以有多个impl T for S(每个X)
  • trait T { type X;}关联类型,只能一个impl T for S
    • type X = R; 在S中设置关联类型impl T for S {type X = R;}
  • impl<T> S<T> {}实现任何类型T在S<T>,这个T类型参数
  • impl S<T> {}例如S<u32>
  • fn f() -> impl T
  • fn f(x: &impl T)
  • fn f(x: &dyn T)
  • fn f() where Self::R;trait T{},让f可认识类型为impl R
    • fn f() where Self::Sized;使用 Sized 可以选择 f 退出 dyn T trait object vtable,启用 trait obj
    • fn f() where Self::R {}其他 R 有用的 w. dflt.方法(反正非dflt.需要拔)

10.higher-ranked 项目

实际类型和traits,某个内容的抽象,通常生命周期

  • for<'a> higer-ranked bounds
  • trait T: for<'a> R<'a> {}
  • fn (&'a u8)
  • for<'a> fn(&'a u8)
    • fn (&'_ u8)
    • fn(&u8)
  • dyn for<'a> Fn(&'a u8)
    • dyn Fn(&'_ u8)
    • dyn Fn(&u8)

11.字符串和字符

  • ...string类型,UTF-8,包含\n
  • r"..." raw string不会有\n
  • r#"..."# 可以包含" #数量可变的
  • b"..." byte string ASCII类型[u8],不是string
  • br"...",br#"..."# raw byte string ASCII类型[u8]
  • '🦀'字符char类型,占4字节
  • b'x' ASCII byte

12.文件注释

  • /// types, traits和functions的doc文档信息
  • //! 模块的开始文件 doc的内联行
  • // 行注释
  • /*...*/ 块注释
  • /**..*/ 外部块注释
  • /*!...*/ 内部块注释

13.杂项

  • ! 永不返回
  • _ 未命名配置
    • let _ = x;x移出这个范围
  • _x
  • 1_234_567
  • 1_u8
  • 0xBEEF, 0o777, 0b1001
  • r#foo
  • x;
posted @ 2022-09-03 18:22  BabyMelvin  阅读(280)  评论(0编辑  收藏  举报