Rust 学习入门记录

111 阅读4分钟

过年的时候,我的生活挺曲折(?),所以决定自我投资,不再想着对别人付出可以获得同等的回报。

感谢 course.rs/about-book.… 这个作者指明了道路,十分感谢。

** 以下是记录 会跟着变化时间变化,如有错误请指出 **

rust

变量

let

  • 在 rust 中是不可变的

  • mut

    • 就说明了这个变量之后会有变化的
  • _

    • 和 go 一样,如果用不上就没用

shadowing 重复声明就会屏蔽前面的声明的

range

  • 左闭右开

    • [0,2]=rang[0,1]

      • 不会包含 2
    • start..=end

      • 这个是左右闭合

#[DERIVE(...)]

  • debug

    • 输出具体的类型
  • clone

    • 复制数据

result

  • 结构

    • ok

    • err

  • unwrap

    • 直接获取里面的值,但是如果这个值是空的会直接程序 panic!
    • 如果遇到 None,或者 Option<中的 Err>就会直接返回错误

配置文件

  • Cargo.toml

基本类型

rust 特有的概念

  • 运算符重载

    • 就是重载(重新定义)运算规则
  • i->有符号

  • u-> 无符号

  • size-> 取的是计算机的位数

    • 和 i,u 组合

      • usize

      • isize

  • f->float 的缩写

    • f32

    • f64

字符,bool,unit(单元)

  • char

    • 这也能是字符?(四个字节)

      • let c = 'z';
        
      • let z = 'ℤ';
        
      • let g = '国';
        
      • let heart_eyed_cat = '😻';
        
      • size_of_val(Z) 无论怎么样都是 4 个字节

    • 所以 rust 中的 char 并不是 1 个字节的,而是一个 unicode

悬垂引用(Dangling References)

  • 就是这个变量已经被回收了,但还是访问了,编译的时候会报错

slince

  • 和 go 的一样

集合类型

  • slice

    • 引用类型(没有数据的所有权)

    • to_vec 可以变成 vec

  • array

    • 一开始就存在并且固定大小,存在于栈中
  • vectorer

    • 存在堆中

    • 变成 to_slince() 变成 slince

    • 如果一个所有权没有,整个不会不能访问 而是只有单个不会访问而已

  • HashMap

    • 大概原理和 正常的HashMap 一致

元组

  • let x: (i32, f64, u8) = (500, 6.4, 1);

    let five_hundred = x.0;

    • 可以这样玩,x.1 但是这个很难做

结构体

  • 和 go 不一样的是一样要指定具体的值

  • 可变化,只能这个结构体一起变化,不能只变化结构体中单一的字段

  • 如果入参和结构体同名,初始化的时候就可以省去这个步骤

    • fn build_user(email: String, username: String) -> User { User { email, username, active: true, sign_in_count: 1, } }
  • 已知道的 结构体复制,如果在命名相等的情况下

    • 可以通.<..> 去赋值,不过需要注意的是一定要在句子的尾部(和 go 有点相似,但又完全不一样)
  • option 在这里设置了就可以做到可选的标志

  • 单元结构体(Unit-like Struct)

    • 就是多一个 let

关键字 ref 和&的区别

  • 没太大区别

Enum

  • 枚举的变体不能赋值为浮动类型

  • option

    • some

      • 表示有值进入
    • none

      • 就是rust 中表达的 nil 的意思

所有权

  • 借用

    • 通过指针,去共享这个变量的使用权

    • &T 不可变借用

      • 只能引用,不能调用
    • &mut t 可变兼容,如果传值的时候,需要注意的

  • 所有权转移

    • 每个人都有一个所有者,当所有者离开作用域时候,就会被丢弃
  • 引用

流程控制

大部分和 golang 一样 就是没有 switch

  • 因为 switch 概念被 match 获取了

loop

while

label

  • 'outer: for i in 1..=3 { for j in 1..=3 { if i == 2 && j == 2 { break 'outer; } println!("i = {}, j = {}", i, j); } }

匹配模式

match

  • 必须列举所有可能性

  • 每个分支返回的格式要一样

  • 可以用 逻辑运算符 |和&

  • _ 就是 default

match!宏

  • 感觉就是 TypeScript 的语法糖

    • assert!(matches!(foo, 'A'..='Z' | 'a'..='z'));

if let 匹配

  • 如果只有一个就用 if let,不然就用 match 这样可以带来代码的结构性优化

METHODS

self 的学问

  • self

  • &self

  • &mut self

Module

  • 方法限制

    • pub

      • 无任何限制
    • pub(create)

      • 当前包可见
    • pub(super)

      • 父模块课件
    • pub(in )

      • 父模块或者祖先模块,可见
  • use 应用的格式

泛型

const

  • const fn

  • const

类型_T

  • 显示告诉泛型具体是怎么用的

特征 Traits

特征对象

  • 是静态分发的

trail

  • 和interface 差不多 不过不需要完全实现

  • clone

存储细节

存储细节

  • stack

    • 因为build 的时候就会生成,所以比较快
  • heap

    • 在 build 之后然后再增加/减少,所以比较慢

生命周期

生命周期流程

  • 这个和作用域绑定

  • 如果有指针,就要加一个生命周期表示

生命周期消除

  • method 入参

    • 只有一个参数非 self

      • 输出的所有权会被覆盖
    • 只有一个 self

      • &self and &mut self

        • 这个时候 self 只是借用而已,所有权不会变跟
      • self

        • 会被 self 覆盖

        • 只有在 self 新创建的所有权才属于 self

    • 有 self,并且有多个时候,需要手动标注

      • 所有权获取最少的生命周期的

静态生命周期 'static

  • 相当于全局变量

生命周期方法

  • 如果 impl 的方法需要标注寿命周期这样需要继承这个结构体

文件规格

模块

  • 可以直接 use 来避免一些事情的发生

panic 主动终止的两个方式

panic!

通过 backtrace =1 设置,然后获取错误栈

区别于 golang, 子进程 panic 也不会影响主进程