The Rust Programming Language

  • Rust 开发工具
    • Cargo: 内置的依赖管理器和构建工具
    • Rustfmt: 确保开发者遵循一致的代码风格
    • Rust Language Server 集成开发环境(IDE)提供强大的代码补全和内联错误信息功能

Chapter 1 - 入门指南

  • 1.1 - 安装

    • rustup: 一个管理Rust版本和相关工具的命令行工具

      chyiyaqing in ~ at aapc at ☸️ v1.25.0 kubernetes-admin@kubernetes (istioinaction)  …
      ➜ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
      
    • 检查安装是否正确

      chyiyaqing in ~ at aapc at ☸️ v1.25.0 kubernetes-admin@kubernetes (istioinaction)  took 3.6s …
      ➜ rustc --version
      rustc 1.66.0 (69f9c33d7 2022-12-12)
      
  • 1.2 更新与卸载

chyiyaqing in ~ at aapc at ☸️ v1.25.0 kubernetes-admin@kubernetes (istioinaction)  …
➜ rustup update
info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu'
info: checking for self-updates

  stable-x86_64-unknown-linux-gnu unchanged - rustc 1.66.0 (69f9c33d7 2022-12-12)

info: cleaning up downloads & tmp directories

chyiyaqing in ~ at aapc at ☸️ v1.25.0 kubernetes-admin@kubernetes (istioinaction)  …
➜ rustup self uninstall
  • 1.3 Hello, World!

    main.rs

    fn main() {
      println!("hello, world!");
    }
    

    rustc编译器编译Rust程序

    $ rustc main.rs
    

    Rust是一种预编译静态类型(ahead-of-time compiled)语言

  • 1.4 Hello, Cargo!

Cargo 是Rust的构建系统和包管理器,它可以为你处理很多任务,比如构建代码、下载依赖库并编译这些库.

检查是否安装了Cargo

➜ cargo --version
cargo 1.66.0 (d65d197ad 2022-11-15)

使用Cargo创建项目

chyiyaqing in github.com/rust-in-action-source-code/ch1 at aapc via ⬢ v18.12.1 …
➜ cargo new hello_cargo
     Created binary (application) `hello_cargo` package

构建Cargo项目

chyiyaqing in rust-in-action-source-code/ch1/hello_cargo at aapc on  main [✘] via 🦀 1.66.0 …
➜ cargo build
   Compiling hello_cargo v0.1.0 (/home/chyiyaqing/chyi/github.com/rust-in-action-source-code/ch1/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 2.43s

运行Cargo项目

chyiyaqing in rust-in-action-source-code/ch1/hello_cargo at aapc on  main [✘?] is 📦 0.1.0 via 🦀 1.66.0 at ☸️ kubernetes-admin@kubernetes  …
➜ ./target/debug/hello_cargo
Hello, world!

编译并运行Cargo项目

chyiyaqing in rust-in-action-source-code/ch1/hello_cargo at aapc on  main [✘?] is 📦 0.1.0 via 🦀 1.66.0 at ☸️ kubernetes-admin@kubernetes  …
➜ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/hello_cargo`
Hello, world!

检查代码

chyiyaqing in rust-in-action-source-code/ch1/hello_cargo at aapc on  main [✘?] is 📦 0.1.0 via 🦀 1.66.0 at ☸️ kubernetes-admin@kubernetes  …
➜ cargo check
    Checking hello_cargo v0.1.0 (/home/chyiyaqing/chyi/github.com/rust-in-action-source-code/ch1/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.21s

发布构建Cargo

chyiyaqing in rust-in-action-source-code/ch1/hello_cargo at aapc on  main [✘?] is 📦 0.1.0 via 🦀 1.66.0 at ☸️ kubernetes-admin@kubernetes  …
➜ cargo build --release
   Compiling hello_cargo v0.1.0 (/home/chyiyaqing/chyi/github.com/rust-in-action-source-code/ch1/hello_cargo)
    Finished release [optimized] target(s) in 0.60s

Chapter 2 - 写个猜数字游戏

  • 在Rust中, 变量默认是不可变的
  • associated function: 关联函数
  • crates.io - The Rust community’s crate registry
  • Cargo.lock - 文件确保构建是可重现的
  • cargo update

Chapter 3 - 常见编程概念

  • 关键字 keywords

    • 正在使用的关键字
      • as - 强制类型转换,消除特定包含项的trait的歧义,或者对use语句中的项重命名
      • async - 返回一个Future而不是阻塞当前线程
      • await - 暂停执行知道Future的结果就绪
      • break - 立刻推出循环
      • const - 定义常量或不变裸指针 (constant raw pointer)
      • continue - 继续进入下一次循环迭代
      • crate - 在模块路径中,代指crate root
      • dyn - 动态分发trait对象
      • else - 作为if和if let 控制流结构的fallback
      • enum - 定义一个枚举
      • extern - 链接一个外部函数或变量
      • false - 布尔字面值false
      • fn - 定义一个函数或函数指针类型 (function pointer type)
      • for - 遍历一个迭代器或实现一个traint或者指定一个更高级的生命周期
      • if - 基于条件表达式的结果分支
      • impl - 实现自有或trait功能
      • in - for 循环语法的一部分
      • let - 绑定一个变量
      • loop - 无条件循环
      • match - 模式匹配
      • mod - 定义一个模块
      • move - 使闭包获取其所捕获项的所有权
      • mut - 表示引用,裸指针或模式绑定的可变性
      • pub - 表示结构体字段,impl快或模块的共有可见性
      • ref - 通过引用绑定
      • return - 从函数中返回
      • Self - 定义或实现trait的类型的类型别名
      • self - 表示方法本身或当前模块
      • struct - 定义一个结构体
      • super - 表示当前模块的父模块
      • trait - 定义一个trait
      • true - 布尔字面值true
      • type - 定义个类型别名或关联类型
      • union - 定义个union并且是union声明中唯一用到的关键字
      • unsafe - 表示不安全的代码、函数、trait或实现
      • use - 引入外部空间的符号
      • where - 表示一个约束类型的从句
      • while - 基于一个表达式的结果判断是否进行循环
    • 保留关键字
      • abstract become box do final macro override priv try typeof unsized virtual yield
  • 变量和可变性

    • 变量 变量默认是不可改变的(immutable), 可以在变量名前添加mut来使其可变.

    • 常量(constants) 常量是绑定到一个名称的不允许改变的值,声明常量使用const关键字, 不允许对常量使用mut. Rust对常量的命名约定是在单词之间使用全大写加下划线

    • 隐藏(Shadowing) 定义一个与之前变量同名的新变量,第一个变量倍被第二个隐藏,当你使用变量名称时,编译器将看到第二个变量.

    • 数据类型(data type)

      • 标量(scalar) 标量(scalar)类型代表一个单独的值.

        • 整型 整数是一个没有小数部分的数字, isize, usize, 有符号数以补码形式存储. 有符号范围

          • 整数溢出(integer overflow) 当在debug模式编译时,Rust检查这类问题并使程序panic.

            当在release构建中,Rust不检测溢出,会以一种被称为二进制补码回绕(two’s complement wrapping)的操作.简而言之,比此类型能容纳最大值的值会回绕到最小值

        • 浮点型 Rust有两个原生的浮点数(floating-point numbers)类型,Rust的浮点数类型是f32和f64, 所有的浮点类型都是有符号.

          Rust中所有数字类型都支持基本数学运算: 加法、减法、乘法、除法和取余.

        • 布尔类型 Rust中的布尔类型有两个可能的值: true和false, Rust中的布尔类型使用bool表示

        • 字符类型 Rust的char类型是语言中最原生的字母类型, 使用单引号声明char字面量, 使用双引号声明字符串字面值, Rust的char类型的大小为四个字节(four bytes),并代表一个Unicode标量值(Unicode Scalar Value)

      • 复合类型(compound types) 复合类型可以将多个值组合成一个类型, Rust有两个原生的复合类型

        • 元组(tuple) 元组是一个将多个其他类型的值组合进一个复合类型的主要方式 元组长度固定:一旦声明,其长度不会增大或缩小, 使用点号(.)后跟值的索引访问, 元祖的第一个索引值是0.

        • 数组(array) 数组中的每个元素的类型必须相同,Rust中的数组长度是固定的

  • 函数 Rust代码中的函数和变量名使用snake case规范风格,在snake case中,所有字母都是小写并使用下划线分隔单词.Rust不关心函数定义所在的位置,只要函数被调用时出现在调用之处可见的作用域内就行

    • 参数(parameters) 参数(形参)是特殊变量,是函数签名的一部分.实参(arguments). Rust函数签名中,必须声明每个参数的类型。
    • 语句和表达式 函数体由一系列的语句和一个可选的结尾表达式构成.语句(Statements)是执行一些操作但不返回值的指令,表达式(Expression)计算并产生一个值.表达式可以是语句的一部分. 表达式的结尾没有分号,如果在表达式的结尾加上分号,它就变成了语句,而语句不会返回值
    • 函数的返回值 Rust中函数的返回值等同于函数体最后一个表达式的值.使用return关键字和指定值,可以从函数中提前返回,但大部分函数隐式的返回最后的表达式。
  • 注释 (comments) Rust中,惯用的注释样式是以两个斜杠开始注释,并持续到本行的结尾.

    Rust中另一种注释称为文档注释

  • 控制流

    • if表达式 Rust不会尝试自动将非布尔值转换为布尔值,必须总是显式地使用布尔值作为if的条件.
    • 循环(loops)
      • loop loop关键字告诉Rust一遍一遍执行一段代码直到明确要求停止
      • while
      • for
      • break break关键字告诉程序何时停止循环
      • continue continue关键字告诉程序跳过这个循环迭代中任何剩余代码,并转到下一个迭代

Chapter 4 - 认识所有权

所有权是Rust最与众不同的特性,对语言的其他部分有着深刻含义.它让Rust无需垃圾回收(garbage collector)即可保障内存安全.

所有程序都必须管理其运行时使用计算机内存的方式。一些语言中具有垃圾回收机制,在程序运行时有规律地寻找不再使用的内存,在另一些语言中,程序员必须亲自分配和释放内存。Rust则选择了第三种方式:通过所有权系统管理内存。

  • 所有权 (ownership)

Rust通过所有权系统管理内存,编译器在编译时会根据一系列的规律进行检查,如果违反任何这些规律,程序都不能编译. 在运行时,所有权系统的任何功能都不会减慢程序.

  • 栈 Stack && 堆 Heap 堆和栈都是代码在运行时可供使用的内存.Stack 后进先出(last in, first out), 进栈(pushing onto the stack), 出栈(popping off the stack). 栈中所有数据都必须占用已知且固定的大小,在编译时大小未知或大小可变化的数据要改为存储在堆上。

  • 所有权规则

    • Rust中的每一个值都有一个所有者(owmer)
    • 值的任一时刻有且只有一个所有者
    • 当所有者(变量)离开作用域,这个值将被丢弃
  • 变量作用域(scope)

FAQ

  • [1]: cargo build Unable to update registry crates-io
$ vim ~/.cargo/config

[source.crates-io]
registry = "https://github.com/rust-lang/crates.io-index"

[net]
git-fetch-with-cli=true

Reference materials