Rust 安全代码
安全与非安全代码对比 安全与非安全代码交互 非安全Rust能做什么 编写非安全代码数据布局
repr(Rust) 类型中的奇行种 可选的数据表达方式所有权
所有权 引用 别名 生命周期 生命周期的局限 省略生命周期 无界生命周期 高阶trait边界 子类型和变性 Drop检查 幽灵数据 分解借用类型转换
类型转换 强制类型转换 点操作符 显式类型转换 变形未初始化内存
未初始化内存 安全方式 Drop标志 非安全方式资源管理
基于所有权的资源管理 构造函数 析构函数 泄露展开
展开 异常安全性 污染并发
并发 竞争 Send和Sync 原子操作实现 Vec
实现 Vec 布局 内存分配 push和pop 回收资源 DeRef 插入和删除 IntoIter RawVec Drain 处理零尺寸类型 最终代码FFI
FFIRust 安全代码
安全与非安全代码对比 安全与非安全代码交互 非安全Rust能做什么 编写非安全代码数据布局
repr(Rust) 类型中的奇行种 可选的数据表达方式所有权
所有权 引用 别名 生命周期 生命周期的局限 省略生命周期 无界生命周期 高阶trait边界 子类型和变性 Drop检查 幽灵数据 分解借用类型转换
类型转换 强制类型转换 点操作符 显式类型转换 变形未初始化内存
未初始化内存 安全方式 Drop标志 非安全方式资源管理
基于所有权的资源管理 构造函数 析构函数 泄露展开
展开 异常安全性 污染并发
并发 竞争 Send和Sync 原子操作实现 Vec
实现 Vec 布局 内存分配 push和pop 回收资源 DeRef 插入和删除 IntoIter RawVec Drain 处理零尺寸类型 最终代码FFI
FFIRust 构造函数
创建一个自定义类型的实例的方法只有一种:先命名,然后一次性初始化它的所有成员:
struct Foo {
a: u8,
b:u32,
c: bool,
}
enum Bar {
X(u32),
Y(bool),
}
struct Unit;
let foo = Foo { a: 0, b: 1, c: false };
let bar = Bar::X(0);
let empty = Unit;
就是这样。其他的所谓创建类型实例的方式,不过是调用一些函数,而函数的底层还是要依赖于这个真正的构造函数。
和C++不同,Rust没有很多不同种类的构造函数,比如拷贝、默认、赋值、移动、还有其他各种构造函数。之所以这样的原因有很多,不过归根结底还是因为Rust显式化的设计哲学。
移动构造函数对于Rust没什么用,因为我们并不需要让类型关心它们在内存上的位置。没一个类型都有可能随时被memcopy到内存中其他的位置上。这也意味和那种存储于栈上却依然可以移动的侵入式链表在Rust中是不可能(安全地)存在的。
复制和拷贝构造函数也是不存在的,因为Rust中的类型有且仅有移动语义。x = y只是将y的字节移动到x的变量中。Rust倒是提供了两种和C++中的copy语义相似的功能:Copy和Clone。Clone很像是拷贝构造函数,但是它不会被隐式调用。你必须在需要复制的元素上显式调用clone方法、Copy是Clone的一个特例,它的实现只会拷贝字节码。Copy类型在移动的时候会隐式地复制,但是因为Copy的定义,这个方法只是不把旧的值设置为未初始化而已——其实是一个no-op。
虽然Rust确实有一个Default trait,它与默认构造函数很相似,但是这个trait极少被用到。这是因为变量不会被隐式初始化。Default一般只有在泛型编程中才有用。而具体的类型会提供一个new静态方法来实现默认构造函数的功能。这个和其他语言中的new关键字没什么关系,也没有什么特殊的含义。它仅仅是一个命名习惯而已。
TODO:介绍“placement new”?
下一章:Rust 析构函数
Rust通过Drop trait提供了一个成熟的自动析构函数,包含了这个方法:fn drop(&mut self);这个方法给了类型一个彻底完成工作的机会。drop执行之后,Rust会递归地销毁self的所有成员 ...
AI 中文社