书名 | Rust编程之道 | 作者 | 张汉东中国 |
---|---|---|---|
出版社 | 中国工信出版集团 电子工业出版社 | 阅读日期 | 2019年1月 |
2 语言精要
2.1 Rust语言基本构成
语言规范
编译器 rustc
核心库
标准库
包管理器
2.1.3 核心库
Rust 语言的语法由 核心库 和 标准库 共同提供。其中 Rust 核心库是标准库的基础。
核心库中定义的是 Rust 语言的核心,不依赖于操作系统和网络等相关的库,甚至不知道堆分配,也不提供并发和IO。
可以通过在模块顶部引入#![no std]来使用核心库 。#![no std]
核心库和标准库的功能有一些重复,包括如下部分:基础的 trait,如 Copy、 Debug 、 Display 、 Option 等。
基本原始类型,如 bool、 char、 i8/u8 、 i16/u16 、 i32/u32 、 i64/u64 、 isize/usize 、 f32/f64 、 str、 array 、 slice 、 tuple 、 pointer 等。
常用功能型数据类型,满足常见的功能性需求,如 String 、 Vec 、 HashMap 、 Rc 、 Arc 、 Box 等。
常用的宏定义,如 println! 、 assert!、 panic!、 vec!等。
做嵌入式应用开发的时候,核心库是必需的。
2.1.4 标准库
Rust标准库提供应用程序开发所需要的基础和跨平台支持。
标准库包含的内容大概如下:
- 与核心库一样的基本 trait、原始数据类型、功能型数据类型和常用宏等,以及与核心库几乎完全一致的 API
- 并发、 IO 和运行时。 例如线程模块、用于消息传递的通道类型、 Sync trait 等并发模块,文件、 TCP 、 UDP、管道、套接字等常见 IO 。
- 平台抽象。 OS 模块提供了许多与操作环境交互的基本功能,包括程序参数、环境变量 和目录导航:路径模块封装了处理文件路径的平台特定规则。
- 底层操作接口,比如 std::mem、 std::ptr 、 std: :in trinsics 等,操作内存、指针、调用编 译器固有函数。
- 可选和错误处理类型 Option 和 Result,以及各种选代器等。
2.2 语句与表达式
Rust 中的语法可以分成两大类:
- 语句 ( Statement ) :要执行的一些操作和产生副作用的表达式。
- 表达式 ( Expression ):主要用于计算求值。
语句又分为两种:
- 声明语句 ( Declaration statement ):用于声明各种语言项 (ltem),包括声明变量、静态变量、常量、 结构体、 函数等,以及通过 extern 和 use 关键字引入包和模块等。
- 表达式语句 ( Expression statement ):特指以分号结尾的表达式。此类表达式求值结果将会被舍弃, 并总是返回单元类型() 。单元类型拥有唯一的值, 就是它本身,为了描述方便,将该值称为单元值。 单元类型的概念来自 OCmal,它表示 “没有什么特殊的价值” 。 所以,这里将单元类型作为函数返回值, 就表示该函数无返回值。当然, 通常无返回值的函数默认不需要在函数签名中指定返回类型。
fn main(){
pub fn answer() ->(){
let a = 40;
let b = 2;
assert_eq!(sum(a,b),42);
}
}
编译器解析代码次序
Rust编译器在解析代码时,如果碰到分号,就会继续向后执行;
如果碰到语句,则执行语句;
如果碰到表达式,则会对表达式求值;
如果分号后面什么也没有,就会补上单元值。
当遇到函数时,会将函数体的花括号识别为 Block Expression 块表达式。Block Expression由一对花括号和一系列的表达式组成。它总是返回块中最后一个表达式的值。
2.3 变量和绑定
Binding 绑定 : Identifier 标识符 和 Value 值之间的关联关系。
2.3.1 位置表达式和值表达式
Place Expression 位置表达式:表示内存位置的表达式。
(其他语言一般叫做LValue 左值)分别有几类:
- 本地变量
- 静态变量
- 解引用(*expr)
- 数组索引(expr[expr])
- 字段引用(expr.field)
- 位置表达式组合
通过位置表达式可以对某个数据单元的内存进行读写。主要是进行写操作,这也是位置表达式可以被赋值的原因。
Value Expression 值表达式:除了Place Expression 的表达式就是值表达式。
(其他语言一般叫做RValue 右值)
Value Expression 一般只引用了某个存储单元地址中的数据,它相当于数据值,只能进行读操作。
从语义角度,Place Expression代表了持久性数据,值表达式代表了临时数据。
表达式的求值过程一般在不同的上下文过程中,会有不同的结果。
求值上下文也分为:
- Place Context 位置上下文
- Value Context 值上下文
2.6.3 字符类型
Rust中,使用单引号定义字符 (char)类型。char 是一个 Unicode标量值,每个字符占用4个字节。
2.6.4 数组类型
Array是Rust内建的原始集合类型,数组特点是:
- 数组大小固定
- 元素同等类型
- 默认不可改变
数组签名类型为 [T;N]
T 是一个范型标记;N 代表数组长度,是编译时常量。
2.6.5 范围类型
fn main(){
assert_eq!((1..5),std::ops::Range{start:1,end:5});
println!("{:?}",(1..5));
println!("{:?}",std::ops::Range{start:1,end:6});
}
2.6.8 原生指针
指针:表示内存地址的类型。
Rust提供了多种类型的指针,包括 引用(Reference),原生指针(Raw Pointer),函数指针(fn Pointer)和智能指针(Smart Pointer)
Reference 本质上是一种 非空指针。
Rust可以划分为 Safe Rust 和 Unsafe Rust 两部分。引用主要应用于Safe Rust中。在Safe Rust中,编译器会对引用进行借用检查,以保证内存安全和类型安全。
原生指针主要用于 Unsafe Rust中。直接使用原生指针是不安全的。比如原生指针可能指向一个Null,或者一个已经被释放的内存区域。因为使用原生指针的地方不在safe Rust的可控范围内,所以需要程序员自己保证安全。
rust支持两种原生指针:不可变原生指针 const T 和可变原生指针 mut T。
2.7 复合数据类型
Rust提供 4 种复合数据类型:
- 元组(Tuple)
- 结构体(Struct)
- 枚举体(Enum)
- 联合体(Union)
这4种复合数据类型都是 异构数据结构。
2.7.1 元组
Tuple是一种 异构 有限 序列。