欢迎来到 AI 中文社区(简称 AI 中文社),这里是学习交流 AI 人工智能技术的中文社区。 为了更好的体验,本站推荐使用 Chrome 浏览器。
全部教程·
Rust语言·
Rust高级编程
[目录]
·
强制类型转换
Rust 高级编程
Rust 非安全程序设计
Rust 安全代码
安全与非安全代码对比 安全与非安全代码交互 非安全Rust能做什么 编写非安全代码数据布局
repr(Rust) 类型中的奇行种 可选的数据表达方式所有权
所有权 引用 别名 生命周期 生命周期的局限 省略生命周期 无界生命周期 高阶trait边界 子类型和变性 Drop检查 幽灵数据 分解借用类型转换
类型转换 强制类型转换 点操作符 显式类型转换 变形未初始化内存
未初始化内存 安全方式 Drop标志 非安全方式资源管理
基于所有权的资源管理 构造函数 析构函数 泄露展开
展开 异常安全性 污染并发
并发 竞争 Send和Sync 原子操作实现 Vec
实现 Vec 布局 内存分配 push和pop 回收资源 DeRef 插入和删除 IntoIter RawVec Drain 处理零尺寸类型 最终代码FFI
FFI
Rust 高级编程
Rust 非安全程序设计
Rust 安全代码
安全与非安全代码对比 安全与非安全代码交互 非安全Rust能做什么 编写非安全代码数据布局
repr(Rust) 类型中的奇行种 可选的数据表达方式所有权
所有权 引用 别名 生命周期 生命周期的局限 省略生命周期 无界生命周期 高阶trait边界 子类型和变性 Drop检查 幽灵数据 分解借用类型转换
类型转换 强制类型转换 点操作符 显式类型转换 变形未初始化内存
未初始化内存 安全方式 Drop标志 非安全方式资源管理
基于所有权的资源管理 构造函数 析构函数 泄露展开
展开 异常安全性 污染并发
并发 竞争 Send和Sync 原子操作实现 Vec
实现 Vec 布局 内存分配 push和pop 回收资源 DeRef 插入和删除 IntoIter RawVec Drain 处理零尺寸类型 最终代码FFI
FFIRust 强制类型转换
在一些特定场景中,类型会被隐式地强制转换。这种转换通常导致类型被“弱化”,主要针对指针和生命周期。主要目的是让Rust适用于更多的场景,并且基本上是无害的。
强制转换包括下面几种:
如下几种类型之间允许进行强制转换:
- 传递性:当
T_1可以强制转换为T_2且T_2可以强制转换为T_3时,T_1就可以强制转换为T_3 - 指针弱化:
&mut T转换为&T*mut T转换为*const T&T转换为*const T&mut T转换为*mut T
- Unsize:如果
T实现了CoerceUnsized<U>,那么T可以强制转换为U - 强制解引用:如果
T可以解引用为U(比如T: Deref<Target=U>),那么&T类型的表达式&x可以强制转换为&U类型的&*x
所有的指针类型(包括Box和Rc这些智能指针)都实现了CoerceUnsized<Pointer<U>> for Pointer<T> where T: Unsize<U>。Unsize只能被自动实现,并且实现如下转换方式:
[T; n]=>[T]T=>Trait,其中T: TraitFoo<..., T, ...>=> Foo<..., U, ...>`,其中T: Unsize<U>Foo是一个结构体- 只有
Foo的最后一个成员是和T有关的类型 - 其他成员的类型与
T无关 - 如果最后一个成员的类型是
Bar<T>,那么必须有Bar<T>: Unsize<Bar<U>>
强制转换会在“强制转换位置”处发生。每一个显式声明了类型的位置都会引起到该类型的强制转换。但如果必须进行类型推断,则不会发生类型转换。表达式e到类型U的强制转换位置包括:
- let表达式,静态变量或者常量:
let x: U = e - 函数的参数:
takes_a_U(e) - 函数返回值:
fn foo() -> U {e} - 结构体初始化:
Foo { some_u: e } - 数组初始化:
let x: [U; 10] = [e, ...] - 元组初始化:
let x: (U, ..) = (e, ..) - 代码块中的最后一个表达式:
let x: U = { ..; e }
注意,在匹配trait的时候不会发生强制类型转换(receiver除外,具体见下)。也就是说,如果为U实现了一个trait,T可以强制转换为U,并不能认为T也实现了这个trait。例如,下面的代码无法通过类型检查,虽然t可以强制转换为&T,而且有一个&T的trait实现。
trait Trait {}
fn foo<X: Trait>(t: X) {}
impl<'a> Trait for &'a i32 {}
fn main() {
let t: &mut i32 = &mut 0;
foo(t);
}
<anon>:10:5: 10:8 error: the trait bound `&mut i32 : Trait` is not satisfied [E0277]
<anon>:10 foo(t);
^~~
下一章:Rust 点操作符
点操作符可以做到许多神奇的类型转换任务,比如自动引用,自动解引用,还有级联类型匹配后的强制类型转换。TODO:从这里偷一些信息 stackoverflow.com/questions/2851999...
AI 中文社