Rust 快速参考备忘单,旨在为编写基本语法和方法提供帮助。
入门 配置 vscode 调试 配置参考 。下载 CodeLLDB,选择 rust 自动生成 launch.json 文件
1 2 3 4 5 6 { "configurations" : [ "sourceLanguages" : [ "rust" ] ] }
将编译文件与标准库的位置进行映射
1 2 3 4 5 6 { "lldb.launch.sourceMap" : { "/rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f" : "/Users/feiwu/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust" } }
Hello_World.rs 1 2 3 fn main () { println! ("Hello, World!" ); }
编译运行 1 2 3 4 $ rustc Hello_World.rs $ ./Hello_World Hello, World!
原始类型
:-
:-
bool
布尔值 (true
/ false
)
char
字符
f32
, f64
32 位、64 位浮点数
i64
, i32
, i16
, i8
有符号 16- … 整数
u64
, u32
, u16
, u8
无符号 16 位,… 整数
isize
指针大小的有符号整数
usize
指针大小的无符号整数
查看: Rust 类型
格式化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 println! ("{}" , 1 );println! ("{} {}" , 1 , 3 );println! ("{0} 是 {1} {2},{0} 也是 {3} 编程语言" , "Rust" , "cool" , "language" , "safe" );println! ("{country} 是一个团结的国家" , country = "China" );println! ("让我们打印 76 是二进制的 {:b} ,十六进制等价物是 {:0x} 八进制等价物是 {:o}" , 76 , 76 , 76 );println! ("使用调试特征 {:?} 在此处打印我们想要的任何内容" , (76 , 'A' , 90 ));let x = "world" ;println! ("Hello {x}!" );
打印风格 1 2 3 4 5 6 7 8 print! ("Hello World\n" );println! ("追加新行" );eprint!("这是一个错误\n" ); eprintln!("这是新行的错误" );
变量 1 2 3 4 5 6 7 8 let some_variable = "This_is_a_variable" ;let mut mutable_variable = "Mutable" ;let (name, age) = ("ElementalX" , 20 );const SCREAMING_SNAKE_CASE:i64 = 9 ;
注释
另见: 注释 (doc.rust-lang.org)
函数 1 2 3 4 5 6 fn test (){ println! ("这是一个函数!" ); } fn main (){ test (); }
查看: Functions
声明宏 1 2 3 4 5 6 7 macro_rules! foo { ($l:tt) => { bar!($l); } } macro_rules! bar { (3 ) => {} } foo!(3 );
元变量
:-
:-
item
程序项
block
块表达式
stmt
语句 (注意此选择器不匹配句尾的分号)
pat
模式
expr
表达式
ty
类型
ident
标识符或关键字
path
类型表达式 形式的路径
tt
token
树 (单个 token
或宏匹配定界符 ()
、[]
或 {}
中的标记)
meta
属性,属性中的内容
lifetime
生存期 token
vis
可能为空的可见性限定符
literal
匹配 -?
字面量表达式
结构体 结构体是一个使用关键字 struct
定义的标称型(nominal)结构体类型
1 2 3 struct Point { x: i32 , y: i32 }let p = Point { x: 10 , y: 11 };let px : i32 = p.x;
元组结构体 1 2 struct Color (i32 , i32 , i32 );let black = Color (0 ,0 ,0 );
单元结构体 不关心该类型的内容, 只关心它的行为。
1 2 3 4 struct Solution ;impl Solution { }
语句与表达式 在 rust 中,语句无需返回值,而表达式总要返回值
语句 1 2 3 let a = "hello" .to_string ();let b = a + " world" ;println! ("{}" , b);
表达式 1 2 3 4 5 6 7 8 fn main (){ let x = { let a = "hello" .to_string (); a + " world" }; println! ("{}" , x); }
区间表达式
产生式/句法规则
句法
类型
区间语义
RangeExpr
start..end
std::ops::Range
start ≤ x < end
RangeFromExpr
start..
std::ops::RangeFrom
start ≤ x
RangeToExpr
..end
std::ops::RangeTo
x < end
RangeFullExpr
..
std::ops::RangeFull
-
RangeInclusiveExpr
start..=end
std::ops::RangeInclusive
start ≤ x ≤ end
RangeToInclusiveExpr
..=end
std::ops::RangeToInclusive
x ≤ end
Rust 类型 类型别名 1 2 type Point = (u8 , u8 );let p : Point = (41 , 68 );
整数 1 2 3 4 let mut a : u32 = 8 ;let b = 877_u64 ;let c = 8999i64 ;let d = -90 ;
浮点数 1 2 3 let mut sixty_bit_float : f64 = 89.90 ;let thirty_two_bit_float : f32 = 7.90 ;let just_a_float = 69.69 ;
布尔值 1 2 3 4 let true_val : bool = true ;let false_val : bool = false ;let just_a_bool = true ;let is_true = 8 < 5 ;
字符 1 2 3 4 let first_letter_of_alphabet = 'a' ;let explicit_char : char = 'F' ;let implicit_char = '8' ;let emoji = "\u{1f600}" ;
字符串字面量 1 2 3 let community_name = "AXIAL" ;let no_of_members : &str = "ten" ;println! ("社区的名称是 {community_name},它有 {no_of_members} 个成员" );
查看: 字符串
数组 这里介绍的是固定长度的数组。rust 中常用的是集合类型 vec 表示的动态数组
1 2 3 4 ┌─────┬─────┬─────┬─────┬─────┬─────┐ | 92 | 97 | 98 | 99 | 98 | 94 | └─────┴─────┴─────┴─────┴─────┴─────┘ 0 1 2 3 4 5
1 let array : [i64 ; 6 ] = [92 ,97 ,98 ,99 ,98 ,94 ];
1 2 3 let mut array : [i32 ; 3 ] = [2 ,6 ,10 ];array[1 ] = 4 ; array[2 ] = 6 ;
使用 mut
关键字使其可变
切片 1 2 3 4 let mut array : [ i64 ; 4 ] = [1 ,2 ,3 ,4 ];let mut slices : &[i64 ] = &array[0 ..3 ]println! ("切片的元素是:{slices:?}" );
元组 1 let tuple = (1 , 'A' , "Cool" , 78 , true );
Rust 字符串 字符串字面量 1 2 3 let cs :&str = "备忘清单" ;println! ("为开发者分享 {cs}" );
字符串对象 1 2 3 4 5 6 7 let my_string = String ::new;let S_string = a_string.to_string ()let lang = String ::from ("Rust" ); println! ("First language is {lang}" );
.capacity() 1 2 let rand = String ::from ("Random String" );rand.capacity ()
以字节为单位计算字符串的容量
with_capacity() 1 let s = String ::with_capacity (10 );
指定一个足够大的容量值,来减少内存拷贝
.contains() 1 2 let name = String ::from ("ElementalX" );name.contains ("Element" )
检查子字符串是否包含在原始字符串中
添加单个字符 1 2 let mut half_text = String ::from ("Hal" );half_text.push ('f' );
添加整个字符串 1 2 3 4 let mut hi = String ::from ("Hey there..." );hi.push_str ("How are you doing??" ); println! ("{hi}" );
原生字符串 1 2 3 let str1 = r#"\hello"# ;println! ("{}" , str1);
原生字符串,无需增加转义字符(\
)转义
字节和字节串 1 2 3 4 5 6 7 8 9 let str2 = b'a' ;println! ("{}" , str2);let str3 = b"\\hello" ;println! ("{:?}" , str3);let str4 = br#"\hello"# ;println! ("{:?}" , str4);
Rust 动态数组 创建动态数组 1 2 3 let v : Vec <i32 > = Vec ::new ();let v1 = vec! [1 , 2 , 3 ];
读取元素 1 2 3 4 5 6 7 let v = vec! [1 , 2 , 3 , 4 , 5 ];let element = &v[100 ];let element2 = v.get (100 );println! ("{:?}" , element2);
遍历数组
只读取数组中的元素
1 2 3 4 let v = vec! [1 , 2 , 3 ];for i in &v { println! ("{}" , i); }
遍历的同时修改数组中的元素
1 2 3 4 let mut v = vec! [1 , 2 , 3 ];for i in &mut v { *i += 10 }
多维数组 1 2 3 4 5 6 j0 j1 j2 j3 j4 j5 ┌────┬────┬────┬────┬────┬────┐ i0 | 1 | 2 | 3 | 4 | 5 | 6 | ├────┼────┼────┼────┼────┼────┤ i1 | 6 | 5 | 4 | 3 | 2 | 1 | └────┴────┴────┴────┴────┴────┘
1 2 3 4 let arr = vec! [ vec! [1 , 2 , 3 , 4 , 5 , 6 ], vec! [6 , 5 , 4 , 3 , 2 , 1 ] ];
常用方法
-
:-
len()
返回 vec
的长度
is_empty()
vec
是否为空
push(value)
在 vec
尾部插入元素
pop()
删除并返回 vec
尾部的元素或者返回 None
insert(index,element)
在指定索引处插入元素
remove(index)
删除指定索引处的元素并返回被删除的元素,索引越界将 panic 报错退出
clear()
清空 vec
append(vec)
将另一个 vec
中的所有元素追加移入 vec
中,移动的 vec
变为空
truncate(len)
将 vec
截断到指定长度,多余的元素被删除
retain(f)
根据给定的函数,保留满足条件的元素
drain(range)
删除 vec
中指定范围的元素,同时返回一个迭代该范围所有元素的迭代器
split_off(index)
切分 vec
,索引左边的元素保留在原 vec
中(含索引),索引右边的元素(不含索引)在返回的 vec
中
Rust HashMap<K,V> 使用 1 2 3 4 5 6 7 8 9 10 11 use std::collections::HashMap;fn main () { let mut map : HashMap<String , i32 > = HashMap::new (); map.insert (String ::from ("blue" ), 100 ); let v : &mut i32 = map.entry ("Yellow" .to_string ()).or_insert (5 ); let v : &mut i32 = map.entry ("Yellow" .to_string ()).or_insert (50 ); }
获取元素 1 2 3 4 5 6 7 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 : Option <&i32 > = scores.get (&team_name);
遍历 1 2 3 4 5 6 7 8 let mut scores = HashMap::new ();scores.insert (String ::from ("Blue" ), 10 ); scores.insert (String ::from ("Yellow" ), 50 ); for (key, value) in &scores { println! ("{}: {}" , key, value); }
vec -> HashMap 1 2 3 4 5 6 7 let teams_list = vec! [ ("中国队" .to_string (), 100 ), ("美国队" .to_string (), 10 ), ("日本队" .to_string (), 50 ), ]; let teams_map : HashMap<_,_> = teams_list.into_iter ().collect ();
1 2 3 4 let teams = vec! [String ::from ("blue" ),String ::from ("red" )];let intial_scores = vec! [10 ,50 ];let scores :HashMap<_,_> = teams.iter ().zip (intial_scores.iter ()).collect ();
Option & Result Option 1 2 3 4 enum Option <T> { Some (T), None , }
使用 1 2 3 4 5 6 7 8 fn main (){ let a = Some (5 ); println! ("{}" , a.unwrap ()); let x : Option <&str > = None ; x.expect ("fruits are healthy" ); }
Result 1 2 3 4 enum Result <T, E> { Ok (T), Err (E), }
使用 1 2 3 4 5 6 7 8 9 10 11 use std::fs::File;fn main () { let f : Result <File,Error> = File::open ("hello.txt" ); let f = match f { Ok (file) => file, Err (error) => { panic! ("Problem opening the file: {:?}" , error) }, }; }
宏 ?
?
只能用于返回结果是 Result 或者 Option 的函数,或者实现了 Try 类型
1 2 3 4 5 6 7 8 use std::fs::File;use std::io::{self , Read};fn read_username_from_file () -> Result <String , io::Error> { let mut s = String ::new (); File::open ("hello.txt" )?.read_to_string (&mut s)?; Ok (s) }
1 2 3 4 fn first (arr: &[i32 ]) -> Option <&i32 > { let v = arr.get (0 )?; Some (v) }
枚举 在结构体中使用枚举 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 enum IpAddrKind { V4, V6, } struct IpAddr { kind: IpAddrKind, address: String , } fn main (){ let ip = IpAddr{ kind: IpAddrKind::V4, address: String ::from ("127.0.0.1" ) }; }
枚举的变体 1 2 3 4 5 6 7 8 9 enum IpAddrKind { V4 (u8 , u8 , u8 , u8 ), V6 (String ), } fn main () { let home = IpAddrKind::V4 (127 , 0 , 0 , 1 ); let loopback = IpAddrKind::V6 (String ::from ("::1" )); }
1 2 3 4 5 6 7 8 9 10 11 12 enum Message { Quit, Move {x:i32 , y:i32 }, Write (String ), ChangeColor (i32 , i32 , i32 ), } fn main (){ let q = Message::Quit; let m = Message::Move {x:10 , y:20 }; let w = Message:: Write (String ::from ("hello" )); let c = Message::ChangeColor (10 , 20 , 30 ); }
模式匹配结构体 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #[derive(Debug)] enum Grade { A, B, C, } enum Subject { Math (Grade), English (Grade), } fn subject_grade (sub: Subject) { match sub { Subject::Math (grade) => println! ("The Math is {:?}" , grade), Subject::English (grade) => println! ("The Math is {:?}" , grade), } } fn main () { subject_grade (Subject::Math (Grade::A)); }
Rust 运算符 比较运算符
:-
:-
e == f
e
等于 f
e != f
e
不等于 f
e < f
e
小于 f
e > f
e
大于 f
e <= f
e
小于或等于 f
e >= f
e
大于或等于 f
1 2 3 4 5 6 7 let (e, f) = (1 , 100 );let greater = f > e; let less = f < e; let greater_equal = f >= e; let less_equal = e <= f; let equal_to = e == f; let not_equal_to = e != f;
算术运算符
:-
:-
a + b
a
被添加到 b
a - b
从 a
中减去b
a / b
a
除以 b
a % b
通过与 b
相除得到 a
的余数
a * b
a
与 b
相乘
1 2 3 4 5 6 let (a, b) = (4 , 5 );let sum : i32 = a + b; let subtractions : i32 = a - b; let multiplication : i32 = a * b; let division : i32 = a / b; let modulus : i32 = a % b;
位运算符
运算符
描述
g & h
二进制与
g | h
二进制或
g ^ h
二进制异或
g ~ h
二进制补码
g << h
二进制左移
g >> h
二进制右移
1 2 3 4 5 6 let (g, h) = (0x1 , 0x2 );let bitwise_and = g & h; let bitwise_or = g | h; let bitwise_xor = g ^ h; let right_shift = g >> 2 ; let left_shift = h << 4 ;
逻辑运算符
示例
意义
c && d
两者都是真的_(AND)_
c || d
要么是真的_(OR)_
!c
c
为假 (NOT)
1 2 3 4 let (c, d) = (true , false );let and = c && d; let or = c || d; let not = !c;
复合赋值运算符 1 2 let mut k = 9 ;let mut l = k;
运算符
描述
k += l
添加一个值并赋值,然后 k=9
k -= l
Substrate
一个值并赋值,然后 k=18
k /= l
除以一个值并赋值,然后 k=9
k *= l
乘一个值并赋值,然后 k=81
k |= l
按位或并赋值,则 k=89
Rust 流程控制 If 表达式 1 2 3 4 5 6 7 8 9 10 11 let foo = 12 ;let bar = 13 ;if foo == bar { println! ("foo 等于 bar" ); } else if foo < bar { println! ("foo 小于 bar" ); } else if foo != bar { println! ("foo 不等于 bar" ); } else { println! ("Nothing" ); }
For 循环 1 2 3 4 5 let mut vec = [1 , 2 , 3 ];for v in &mut vec { *v -= 1 ; println! ("v 的值为:{v}" ); }
使用方法
等价使用方式
所有权
for item in collection
for item in collection.into_iter()
转移所有权
for item in &collection
for item in collection.iter()
不可变借用
for item in &mut collection
for item in collection.iter_mut()
可变借用
While 循环 1 2 3 4 5 6 7 8 9 let mut check = 0 ;while check < 11 { println! ("check 是:{check}" ); check += 1 ; println! ("递增后:{check}" ); if check == 10 { break ; } }
Loop 循环 1 2 3 loop { println! ("你好,世界永远!" ); }
无限循环表示
Continue 继续声明 1 2 3 4 5 6 7 8 for (v, c) in (0 ..10 +1 ).enumerate (){ println! ("{c} 数字循环" ); if v == 9 { println! ("我们继续?" ); continue ; } println! {"v 的值为:{v}" }; }
Break 中断语句 break
可以单独使用,也可以带一个返回值
1 2 3 4 5 6 7 8 9 10 let mut i = 1 ;let res = loop { println! ("i 是 {i}" ); if i > 100 { break i - 100 ; } i *= 2 ; } println! ("{res}" );
Rust 模式匹配 match match 模式匹配,使用 a | b
表示匹配 a 或 b,使用 _
,表示匹配剩余所有选项
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 fn main (){ let grade = Grade::A; match grade { Grade::A => println! ("Good" ), Grade::B => println! ("Not bad" ), Grade::C | Grade::D => println! ("Come on" ), _ => println! ("emmm" ), } } enum Grade { A, B, C, D, E, F, }
matches!
宏它可以将一个表达式跟模式进行匹配,然后返回匹配的结果 true
或 false
1 2 assert! (matches!('x' ',A'..='Z' | 'a' ..='z' ));assert! (matches!(Some (101 ), Some (x) if x > 100 ));
if let 匹配 match 表达式需要匹配所有的枚举才能结束,但通常我们只需要匹配我们需要的值
1 2 3 4 5 let x = 3 ;match Some (x) { Some (3 ) => println! ("I guess that x is 3" ), _ => () }
使用 if let
1 2 3 4 let x = 3 ;if let Some (3 ) = Some (x) { println! ("I guess that x is 3" ); }
while let 1 2 3 4 5 6 7 8 9 let mut stack = vec! [];stack.push (1 ); stack.push (2 ); stack.push (3 ); while let Some (top) = stack.pop () { println! ("{}" , top); }
其它模式匹配 for 循环迭代器 1 for (i, v) in collection.iter ().enumerate (){}
let 1 2 let (x, _, y) = (1 , 2 , 3 );println! ("{x},{y}" );
1 2 3 4 5 6 7 fn get_count_item (s: &str ) -> (&str , &str ) { let mut it = s.split (' ' ); let (Some (str1),Some (str2)) = (it.next (),it.next ()) else { panic! ("Can't segment count item pair" ); }; (str1, str2) }
函数中的模式匹配 1 2 3 4 5 6 7 8 fn add ((x, y): (i32 , i32 )) -> i32 { x + y } fn main (){ let sum = add (1 , 2 ); println! ("{sum}" ); }
忽略参数 使用 ..
忽略剩余参数 1 2 3 4 5 6 7 8 9 10 11 struct Point { x: i32 , y: i32 , z: i32 , } let origin = Point { x: 0 , y: 0 , z: 0 };match origin { Point { x, .. } => println! ("x is {}" , x), }
使用 _
忽略部分参数 1 2 3 4 5 6 7 let hello = ('h' , 'e' , 'l' , 'l' , 'o' );match hello { (h, _, _, l, o) => { println! ("char: {}, {}, {}" , h, l, o) }, }
匹配命名变量 以下代码,只要给定的 x 是 Some 类型,但 Some 中的值不是 1,都会匹配到 y
1 2 3 4 5 6 let x = Some (10 );match x { Some (1 ) => println! ("x = 1" ), Some (y) => println! ("y = {:?}" , y), _ => println! ("None" ), }
@
绑定@
运算符允许为一个字段绑定另外一个变量。
1 2 3 4 5 let grade = 'A' ;match grade { good @ 'A' ..='C' => println! ("your grade is {}" , good), _ => println! ("Come on" ), }
1 2 3 4 5 6 7 8 9 10 #[derive(Debug)] struct Point { x: i32 , y: i32 , } fn main (){ let p @ Point {x: px, y: py } = Point {x: 10 , y: 23 }; println! ("x: {}, y: {}" , px, py); println! ("{:?}" , p); }
如果使用 |
,需要使用 ()
,进行多个模式的绑定
1 2 3 4 5 6 match 1 { num @ (1 | 2 ) => { println! ("{}" , num); } _ => {} }
使用匹配守卫 1 2 3 4 5 6 let x = Some (2 );match x { Some (1 ) => println! ("x = 1" ), Some (y) if y == 2 => println! ("y = {:?}" , y), _ => println! ("No match" ), }
Rust 函数 函数命名 rust 的函数使用蛇形命名法(snake case)
1 2 3 fn print_message (){ println! ("Hello, Quick Reference!" ); }
参数值 rust 需要为函数的参数标明确定的类型
1 2 3 4 5 6 7 8 fn another_fn (a:u8 , b: &str ){ println! ("我是 u8:{}" , a); println! ("我是 &str:{}" , b); } fn main (){ another_fn (10 , "hello" ) }
返回值 如果不指定返回值,rust 默认返回 ()
类型
使用 ->
指定返回值,如果表达式 在最后一行,无需使用 return
1 2 3 4 5 6 fn add (a:i32 , b:i32 ) -> i32 { if a + b < 100 { return a - b; } a + b }
永不返回 !
1 2 3 fn dead_end () -> ! { panic! ("panic!!!!!" ); }
惯用转换 &str -> String 1 2 3 String ::from ("str" );"str" .to_string ();"str" .to_owned ();
&str -> &[u8]
或者你也可以使用 b""
1 println! ("{:?}" , b"str" );
&str -> Vec 1 2 "str" .as_bytes ().to_vec ();"str" .as_bytes ().to_owned ();
String -> &str 1 2 let s = String ::from ("str" );let r = s.as_str ();
String -> &[u8] 1 2 let s = String ::from ("str" );let v = s.as_bytes ();
String -> Vec 1 2 let s = String ::from ("str" );let v = s.into_bytes ();
&[u8] -> &str 1 2 let b = "str" .as_bytes ();let str = std::str ::from_utf8 (b).unwrap ();
&[u8] -> String 1 2 let b = "str" .as_bytes ();let str = String ::from_utf8 (b.to_vec ()).unwrap ();
&[u8] -> Vec 1 2 let b = "str" .as_bytes ();let str = b.to_vec ();
1 2 let b = "str" .as_bytes ();let str = b.to_owned ();
Vec -> &str 1 2 let b = "str" .as_bytes ().to_vec ();let s = std::str ::from_utf8 (&b).unwrap ();
Vec -> &[u8] 1 2 let b = "str" .as_bytes ().to_vec ();let s = b.as_slice ();
Vec -> String 1 2 let b = "str" .as_bytes ().to_vec ();let s = String ::from_utf8 (b).unwrap ();
杂项 类型断言 type-casting 1 2 3 let a_int = 90 ; let mut type_cast = (a_int as f64 );
1 2 3 let orginal : char = 'I' ;let type_casted : i64 = orginal as i64 ;
要在 Rust
中执行类型转换,必须使用 as
关键字
借用 1 2 3 let mut foo = 4 ;let mut borrowed_foo = &foo;println! ("{borrowed_foo}" );
1 2 3 let mut bar = 3 ;let mut mutable_borrowed_bar = &mut bar;println! ("{mutable_borrowed_bar}" );
这里借用的值使用 &
运算符从值一中借用值
解引用 1 2 3 let mut borrow = 10 ;let deref = &mut borrow;println! ("{}" , *deref);
*
操作符用于解引用
作用域 1 2 3 4 5 { let a_number = 1 ; } println! ("{a_number}" );
这将产生错误,因为变量 a_number
的生命周期在大括号处结束
另见