Rust 快速指引

install

  • rustup
    • rustc
    • cargo
  • cargo cmd
    • cargo run
    • cargo build --release
    • cargo install 安装二进制命令
    • cargo add .. 安装依赖
    • cargo test 运行时 #[cfg(test)] 属性,条件编译生效

language

  • conditional

    • continue/break 支持标签 'tag 跳出

    • loop 唯一返回有意义值的循环结构,保证至少被输入一次

    • for 语句支持对数组进行迭代(但不支持元组)

    • rust 中没有传统的 for (i = 0; i < 3; i++)

    • 更倾向于使用迭代器(iterator)for 循环结构来进行循环操作

  • type

    • array [T;N]
    • tuple (T,) t.0
    • <T=b> 表示在泛型类型参数T没有明确指定类型的情况下,将使用类型 b 作为默认类型
  • match

    • match 支持 guard,

         #[test]
         fn test_match_usage() {
             let input = 'x';
             match input {
                 'q' => println!("Quitting..."),
                 'a' | 's' | 'w' | 'd' => println!("Movining..."),
                 '0'..='9' => println!("number input"),
                 key if key.is_lowercase() => println!("Lowercase: {key}"),
                 _ => println!("other..."),
             }
         }
      
  • let 控制流

    • if let 表达式

    • while let

    • let else expressions

    • “else” 分支必须执行不同的结束方式, 如 return、break 或 panic

    • let else

      fn hex_or_die_trying(maybe_string: Option<String>) -> Result<u32, String> {
        let Some(s) = maybe_string else {
            return Err(String::from("got None"));
        };
        let Some(first_byte_char) = s.chars().next() else {
            return Err(String::from("got empty string"));
        };
        let Some(digit) = first_byte_char.to_digit(16) else {
            return Err(String::from("not a hex digit"));
        };
      
        return Ok(digit);
      }
      
  • references

    • let mut x_coord: &i32 vs let x_coord: &mut i32
    • 前者是共享引用,可以改变 目标值 x_coord
    • 后者是独占引用,可以改变持有的引用值内容,但不可改变目标值 x_coord
    • rust 中只有可变变量才能创建可变引用
    • ```
      fn main() {
          let mut x = 5;
          let y = &mut x; // 创建对可变变量 x 的可变引用 y
          *y += 1; // 通过可变引用修改变量 x 的值
          println!("x: {}", x); // 输出修改后的 x 的值
      }
      ```
  • Macros

    • assert_ne assert_eq assert
  • Error

    • e @ Err(_) vs Err(e)
    • 前者 e 值 绑定 Err(_), 后者绑定 _
    • Some(val @ 1..=10) @值捕获
  • std lib

    • core 嵌入式常用,大部分不依赖 libc 或 操作系统上的分配器
    • alloc 全局堆分配器 Vec,Box,Arc
    • std

Trait

  • 比较

    • PartialEq and Eq (eq 自反性)
    • PartialOrd and Ord partial_cmp
  • 运算符

    • std::ops Add…
  • FromInto 类型转换

    • 实现 From 后,系统会自动实现 Into
  • as 显式强制类型转换

  • ReadWrite 对 u8 来源进行抽象化处理

  • Default 为类型生成默认值

    • 可以通过 #[derive(Default)] 派生出它
    • 若为结构体,则其中所有类型也都必须实现 Default
  • 闭包 Fn FnMut FnOnce

    • 默认情况下,闭包会依据引用来捕获数据(如果可以的话)
    • move 关键字则可让闭包依据值 来捕获数据
  • 支持trait 嵌套组合

    • 示例

          trait TraitA {
          fn method_a(&self);
          }
      
          trait TraitB {
              fn method_b(&self);
          }
      
          trait CombinedTrait: TraitA + TraitB {
              fn combined_method(&self) {
                  self.method_a();
                  self.method_b();
              }
          }
  • 动态分发

    • Box<dyn Pet>

      Mem

  • 程序分配内存

    • 栈:局部变量的连续内存区域。
    • 值在编译时具有已知的固定大小。
    • 速度极快:只需移动一个栈指针。
    • 易于管理:遵循函数调用规则。
    • 优秀的内存局部性。
    • 堆:函数调用之外的值的存储。
    • 值具有动态大小,具体大小需在运行时确定。
    • 比栈稍慢:需要向系统申请空间。
    • 不保证内存局部性。
  • 内存管理方法

    • 通过手动内存管理实现完全控制: c, c++,pascal...
    • 运行时通过自动内存管理实现完全安全: java,python,go..
    • Rust通过编译时强制执行正确内存, 基于明确的所有权实现
  • 移动语义

    • 默认移动语义,但实现Copy trait类型则会默认复制
    • 在Rust中,克隆是显式的
    • 通常的做法是,先使用克隆操作解决借用检查器问题,在后续通过优化消除这些克隆操作
  • Copy VS Clone

    • 复制是指内存区域的按位复制,不适用于任意对象。
    • 复制不允许自定义逻辑(不同于 C++ 中的复制构造函数)。
    • 克隆是一种更通用的操作,也允许通过实现 Clone trait 来自定义行为。
    • 复制不适用于实现 Drop trait 的类型。
  • std::mem::drop

    • 只是一个采用任何值的空函数。
    • 重要的是它获得了值的所有权,因此在其作用域结束时便会被丢弃
  • references 借用检查

    • shared references 一个或多个共享引用,只读
    • exclusive reference 独占引用,可读写
  • 内部可变性 Interior Mutability

    持有共享引用又可以改变数据

    • Cell 非运行时借用检查, 使用&self移动语义 通过get/set支持内部可变
    • RefCell 强制运行时借用检查 borrow/borrow_mut
    • Rc 多引用计数允许只读访问,不支持内部可变性
  • slice

    • 切片提供对集合 collections 的视图 view
    • 切片从被切片的类型中借用borrow
    • 等价
    • &a[0..a.len()] 与 &a[..a.len()]
    • &a[2..a.len()] &a[2..]
    • &a[..]
  • lifetimes

    • 函数
    • 每个没有生命周期注解的参数都会添加一个生命周期注解
    • 如果只有一个参数生命周期,则将其赋予所有未加注解的返回值
    • 如果有多个参数生命周期,但第一个是self的,则将该 生命周期赋予所有未加注解的返回值
    • 结构体
    • 如果数据类型存储了借用的数据,则必须对其添加生命周期注解
  • 迭代器 (next方法决定迭代视图)

    • Iterator 迭代器操作
    • 元素操作 next map filter...
    • 迭代器方法 for 循环, collect 方法…
    • IntoIterator into_iter
    • IntoIterator::into_iter 获取 self 所有权
    • FromIterator collect
    • FromIterator 可通过 Iterator 构建一个集合
    • implementations of FromIterator for Vec, HashMap, etc
  • 指针

    • Reference 引用 & Rust 中最常见的指针类型

    • &i32 不可变引用

    • &mut i32 表示对 i32 类型的可变引用

    • Raw Pointer 裸指针

      没有所有权和生命周期的指针,不受 Rust 的安全性检查限制,需要手动确保操作的内存是有效的

    • *const T 不可变裸指针

    • *mut T 可变裸指针

    • 智能指针

    • Box<T> 表示拥有 T 类型所有权的指针, 在堆上分配

    • Rc、Arc 用于实现共享所有权

    • Cell、RefCell 内部可变性

    • Mutex 通过互斥锁 locktry_lock 来实现内部可变性

Mod

  • crate 根目录

    • src/lib.rs(对于库 crate, 入口文件)
    • src/main.rs(对于二进制文件 crate)
  • 层次结构

    • 若省略模块内容,则会指示 Rust 在另一个文件中查找:

      ```
          mod garden;
      ```
    • module/mod.rs rust2018 之前

    • 引入filename.rs 来替代filename/mod.rs

    • 即使主模块是文件,更深层次嵌套也可以使用文件夹

      ```
          src/
          ├── main.rs
          ├── top_module.rs
          └── top_module/
              └── sub_module.rs
      ```
    • Rust 寻找模块的位置可通过编译器指令更改

             #[path = "some/path.rs"]
             mod some_module;
  • 可见性

    • 默认情况下,模块项是私有的
    • 父项和同级子项始终可见
    • pub(crate) 关键字来指定一个项(函数、结构体、枚举等)在当前 crate 中可见,但在其他 crate 中不可见。
  • 路径

    • pub use 重新导出
    • fooself::foo 是指当前模块中的 foo
    • crate::foo 是指当前 crate 的根中的 foo 绝对路径
    • bar::foo 是指bar crate 中的foo,绝对路径

Test

  • Rust 中,空的代码块 {} 是一个表达式,它的值是 (),表示一个空的元组
  • test/ 目录支持集成测试
  • lint / Clippy 静态代码分析工具
本作品采用《CC 协议》,转载必须注明作者和本文链接
pardon110
讨论数量: 1

这个东西对于有点编程基础的来说,学习路线依然陡峭。

3周前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
开发者 @ 社科大
文章
134
粉丝
24
喜欢
101
收藏
55
排名:106
访问:8.9 万
私信
所有博文
社区赞助商