Back
Featured image of post rust基础

rust基础

rust基础

1. 工具简介

位置是在 ~/.cargo/bin 下面

  1. rustup 版本控制工具
  2. rustc 编译命令
  3. cargo 包管理工具
  4. rustfmt 自动化格式工具
rustup self uninstall

2. 基本入门

  1. cargo new == cargo check 创建新的项目,toml 制定了 项目的名称、版本、作者以及要使用的 Rust 版本, dependencies 指定了依赖的版本
  2. 代码包被称为 crates。也就是库文件
  3. cargo run 构建并运行项目
  4. cargo build --release 发布 release 文件到 target/release 目录下
  5. 变量默认不可变,声明变量使用 let
  6. ::new 关联函数,也叫静态方法
  7. & 表示这个参数是一个 引用(reference)
  8. expect 方法是 std::result 的一个方法
  9. 以下为几个常用的库
    1. use std::io;
    2. use std::cmp::Ordering;
    3. use rand::Rng;
  10. 分支(arms

3. 数据类型

  1. 标量类型(scalar):类型代表一个单独的值,四种基本的标量类型:整型、浮点型、布尔类型和字符类型
  2. debug 模式整型溢出会panic,release模式不检出
  3. isize 和 usize 类型依赖运行程序的计算机架构:64 位架构上它们是 64 位的, 32 位架构上它们是 32 位的。
  4. 基础数据类型
    1. 整型
      1. i8 u8
      2. i16 u16
      3. i32 u32
      4. i64 u64
      5. i128 u128
      6. isize usize
    2. 浮点(默认类型是 f64):
      1. f32
      2. f64
    3. 布尔
      1. true
      2. false
    4. 字符类型(char 由单引号指定,不同于字符串使用双引号 类型的大小为四个字节(four bytes),并代表了一个 Unicode 标量值
      1. 在 Rust 中,拼音字母(Accented letters),中文、日文、韩文等字符,emoji(绘文字)以及零长度的空白字符都是有效的 char 值。Unicode 标量值包含从 U+0000 到 U+D7FF 和 U+E000 到 U+10FFFF 在内的值。
    5. 复合类型
      1. 元组是一个将多个其他类型的值组合进一个复合类型的主要方式。元组长度固定:一旦声明,其长度不会增大或缩小。模式匹配解构外,也可以使用点号(.)后跟值的索引来直接访问它们
        1. let tup: (i32, f64, u8) = (500, 6.4, 1);
          
    6. 数组类型
      1. 与元组不同,数组中的每个元素的类型必须相同,因为 Rust 中的数组是固定长度的:一旦声明,它们的长度不能增长或缩小。
      2. 当你想要在栈(stack)而不是在堆(heap)上为数据分配空间(第四章将讨论栈与堆的更多内容),或者是想要确保总是有固定数量的元素时,数组非常有用。但是数组并不如 vector 类型灵活。vector 类型是标准库提供的一个 允许 增长和缩小长度的类似数组的集合类型。当不确定是应该使用数组还是 vector 的时候,你可能应该使用 vector
        1. let a = [3; 5];
        2. let a: [i32; 5] = [1, 2, 3, 4, 5]; 如果我们访问数组结尾之后的元素会发生什么呢?比如你将上面的例子改成下面这样,这可以编译通过,不过在运行时会因错误而退出:

4. 函数

  1. 字母都是小写并使用下划线分隔单词
  2. 函数定义以 fn 开始并在函数名后跟一对圆括号
  3. 函数参数
    1. fn another_function(x: i32)
    2. 我们用来创建新作用域的大括号(代码块),{},也是一个表达式
    3. 表达式不带分号,携带分号的是语句

5. 表达式

  1. if 表达式 后面没有括号
  2. loop、while 和 for。

6. 所有权(ownership)

  1. 无需垃圾回收(garbage collector)即可保障内存安全

6.1. 栈(Stack)与堆(Heap)

  1. 入栈比在堆上分配内存要快,因为(入栈时)操作系统无需为存储新数据去搜索内存空间;其位置总是在栈顶。

6.2. 所有权规则

  1. Rust 中的每一个值都有一个被称为其 所有者(owner)的变量。

  2. 值在任一时刻有且只有一个所有者。

  3. 当所有者(变量)离开作用域,这个值将被丢弃。

  4. 所以能够存储在编译时未知大小的文本。可以使用 from 函数基于字符串字面值来创建 String

  5. s 离开作用域的时候。当变量离开作用域,Rust 为我们调用一个特殊的函数。这个函数叫做 drop

  6. 字符串拷贝是移动,是浅拷贝,拷贝完了会被释放,深度拷贝是clone

  7. 如果是简单标量,是可以直接等于的,如果是需要分配内存的,是不可以直接等于的,如果等于的话所有权释放

  8. 引用可以规避作用域,符号为 & 解引用为 *

  9. 一个作用域只能有一个可变应用,编译时就避免数据竞争

  10. 不能在拥有不可变引用的同时拥有可变引用

  11. 悬垂引用(Dangling References)所谓悬垂指针是其指向的内存可能已经被分配给其它持有者

6.2.1. 所有权原则

  1. 在任意给定时间,要么 只能有一个可变引用,要么 只能有多个不可变引用。
  2. 引用必须总是有效的。

6.3. slice

  1. 字符串 slice range 的索引必须位于有效的 UTF-8 字符边界内

7. 结构体

  1. 添加trait #[derive(Debug)]
  2. 关联函数不同于方法不 以 self 作为参数的函数,每个结构体都允许拥有多个 impl 块。

8. 枚举

  1. 示例 enum Message { Quit, Move { x: i32, y: i32 }, Write(String), ChangeColor(i32, i32, i32), }
  2. option 用来表示None值所需 enum Option { Some(T), None, }

9. 方法式编程

  1. 闭包(Closures),一个可以储存在变量里的类似函数的结构
  2. 迭代器(Iterators),一种处理元素序列的方式