rust语法基础
cargo:cargo new/build/run/check;
1变量:
- let定义变量,默认不可变,若想真正可变加关键字mut;
- 常量:用关键词const ,大写加下划线。
- 数组:let a: [i32; 5] = [1, 2, 3, 4, 5]; 访问用a[0]
- 元组:let x: (i32, f64, u8) = (500, 6.4, 1); 访问用a.0 //数组必须是同类变量;元组封装不同类变量
- 向量:
2函数:
- 不关心被调用函数是定义在调用之前还是之后;
- 如果利用函数返回值作为表达式给一个变量赋值,被调函数原型结尾不用有分号;
- 注释:用//
3 控制流:
- 选择分支:if/else if,表达式不带括号
- 循环分支:loop / while 条件表达式/for element in arry,break和continue和C一样;
3 变量的范围(所有权和引用与签名):
所有权、借用和切片的概念确保了 Rust 中程序的内存安全 。Rust 语言让你控制你的内存 用法与其他 Systems 编程语言相同,但具有 数据所有者会在所有者超出范围时自动清理该数据 意味着您不必编写和调试额外的代码来获得此控制权。
- 栈的速度比堆快(分配查找)。
- 基本数据类型的变量赋值给另一个变量的正常拷贝没问题,但对于字符串类型,变量赋值,函数的参数及返回值要特别注意变量的作用域(编译器根据作用域自动释放使其无效)。
- 可变引用、不可变引用、悬空引用。
- 切片:
5结构体:
- 和C的struct一样,形式是K:V;与元组不同的是不需要顺序填充和访问,且在作为函数参数时元组必须指定每个元素类型
- 元组结构:
- 无任何字段的结构=联合体?
- 不能对结构体的某个字段设置mut,只能是整个struct.
- 结构体调试打印:
1 #[derive(Debug)] 2 struct Rectangle { 3 width: u32, 4 height: u32, 5 } 6 7 fn main() { 8 let rect1 = Rectangle { 9 width: 30, 10 height: 50, 11 }; 12 13 println!("rect1 is {rect1:?}"); 14 // 或者用以下 dbg!(&rect1); 15 16 }
- 方法:impl,可以有多个方法。不和struct定义写在一起,但impl写法中可以直接定义元素代替struct.
6枚举:
- 枚举的元素可以是基本类型,可以是函数,也可以是不同类型
- 枚举元素的引用用::符号
- NULL:
- match匹配:对enum的值用match匹配,不同类型对应不同操作方法,其中default可以用other或占位符_代替。
- if let匹配
7模块和软件包:
- 每个.rs文件都可以作为一个模块,多个模块可以组成一个具有一定能够的package,用cargo创建工程,cargo.toml类似一个模块构建的配置文件。一个包可以同时包含一个 src/main.rs 二进制 crate root 以及 src/lib.rs 库 crate root.通常在lib.s中编写结构体定义及方法,模块关系类似于C的头文件,具体实现分布在在src/下的各个文件夹下。
模块按模块树组织:私有和有(默认枚举是公有的,其它函数、结构体、模块都是私有的)。模块(关键词mod)定义可以嵌套,模块的原子元素是函数fn,模块树应在 src/lib.rs 中定义。
1 crate 2 └── front_of_house 3 ├── hosting 4 │ ├── add_to_waitlist 5 │ └── seat_at_table 6 └── serving 7 ├── take_order 8 ├── serve_order 9 └── take_payment 10 //模块签名:restaurantcargo new restaurant --lib 11 //src/lib.rs 12 mod front_of_house { 13 mod hosting { 14 fn add_to_waitlist() {} 15 16 fn seat_at_table() {} 17 } 18 19 mod serving { 20 fn take_order() {} 21 22 fn serve_order() {} 23 24 fn take_payment() {} 25 } 26 } 27 28 29 // main.rs 30 use crate::garden::vegetables::Asparagus; 31 32 pub mod garden;
- 相对路径和绝对路径:路径分隔符::,绝对路径是从crate开始,相对路径是当前文件,也可以从supper开始相对路径;通过using关键词将路径引入当前范围后,模块的函数就不必带长长的路径了。通过as引入别名防止命名冲突using ..as..;可以使用嵌套路径使写法简洁:
路径嵌套1 use std::io; 2 use std::io::Write; 3 //上面的可以用下面替代 4 use std::io(self,Write);
8集合:
-
vector: 智能用来存储同类类型,但可以先通过枚举定义元素,再用向量就可以存储实际不同的东西。
- 字符串:创建,切片,合并,索引。
- 哈希:use std::collections::HashMap; let mut scores = HashMap::new(); scores.insert(String::from("Blue"), 10);
9错误处理:
- 可恢复和不可恢复错误
- 不可恢复错误panic :停止运行
- 可恢复错误用result,catch,扩展错误运算符?去捕捉错误并给出对策。
- 逻辑上的bug:
10泛型类型,特征和生命周期:
- 对于只因参数类型不同,元素数量不同,而功能相同的重复代码可以提取出抽象函数。
- 结构体泛型:结构名称后面的尖括号 struct Point<T> { x: T, y: T, };枚举泛型:enum Result<T, E> { Ok(T), Err(E), };泛型方法;泛型不会降低效率。
- 共享行为trait
- lifttime
11自动化测试:
- assert!宏;assert_eq!、assert_nq!宏;Panics,should_panics宏。
测试框架:
1 #[cfg(test)] 2 mod tests { 3 use super::*; 4 5 #[test] 6 fn it_works() { 7 let result = add(2, 2); 8 assert_eq!(result, 4); 9 } 10 11 #[test] 12 #[ignore] 13 fn expensive_test() { 14 // code that takes an hour to run 15 } 16 }
- 单元测试(库及私有实现细节),集成测试(各部分协同),文档测试。
- 测试驱动开发步骤:1编写1个预期失败的例子,运行得到结果;2编写代码以通过测试;
- 标准输出和错误输出:eprintln!将错误输出到指定文件。
12闭包和迭代器:
- 闭包:||是一种可以捕获环境中的变量,类型有编译器推断的匿名函数,常用于集合操作(如
iter().map())、线程创建(thread::spawn)等场景,相比普通函数更灵活且能保持上下文状态,分带参数和不带参数。 - 迭代器:顺序高效(性能不输手动循环)安全访问(不获取所有权的引用访问)集合元素,是惰性的只有到最后遇到sun等方法时才执行,闭包+map实现元素转换;闭包+filter实现条件过滤;闭包+fold实现累积计算。
13 构建和配置:
- 构建配置:cargo.toml中配置了优化级别(分debug和release),cargo元数据:定义包的名称(共享在先来后到下避免冲突)版本等消息。
- 共享分发到crates.io(先注册): ///用于文档注释,最终生成支持markdown的html文档在doc下,最后cargo publish ;拉取某个版本:cargo yank --vers 1.0.1
- 工作区:通过cargo命令创建依赖关系。
浙公网安备 33010602011771号