欢迎来到 AI 中文社区(简称 AI 中文社),这里是学习交流 AI 人工智能技术的中文社区。 为了更好的体验,本站推荐使用 Chrome 浏览器。
全部教程·
Rust语言·
Rust高级编程
[目录]
·
高阶trait边界
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 高阶trait边界
Rust的Fn trait是个神奇的存在。比如,我们可以写出这样的代码:
struct Closure<F> {
data: (u8, u16),
func: F
}
impl<F> Closure<F>
where F: Fn(&(u8, u16)) -> &u8,
{
fn call(&self) -> &u8 {
(self.func)(&self.data)
}
}
fn do_it(data: &(u8, u16)) -> &u8 { &data.0 }
fn main() {
let clo = Closure{ data: (0, 1), func: do_it };
println!("{}", clo.call());
}
如果我们像在生命周期那一章里一样地去掉这段代码的语法糖,我们会发现一些问题:
struct Closure<F> {
data: (u8, u16),
func: F,
}
impl<F> Closure<F>
// where F: Fn(&'??? (u8, u16)) -> &'??? u8,
{
fn call<'a>(&'a self) -> &'a u8 {
(self.func)(&self.data)
}
}
fn do_it<'b>(data: &'b (u8, u16)) -> &'b u8 { &'b data.0 }
fn main() {
'x: {
let clo = Closure { data: (0, 1), func: do_it };
println!("{}", clo.call());
}
}
我们究竟应该怎么表示F的trait边界里的生命周期呢?这里需要一个生命周期,但是在我们进入call函数之前我们都不知道生命周期的名字!而且,那里的生命周期也是不固定的,&self在那一时间点上是什么生命周期,call就也要是什么生命周期。
这里我们需要借助高阶trait边界(HRTB, Higher-Rank Trait Bounds)的神奇力量了。我们去掉语法糖之后的代码应该是这样的:
where for<'a> F: Fn(&'a (u8, u16)) -> &'a u8,
(其中Fn(a, b, c) -> d本身就是不确定的Fn trait的语法糖)
for<'a>可以读作“对于'a的所有可能选择”,基本上表示一个无限的列表,包含所有F需要满足的trait边界。不过别紧张,除了Fn trait之外我们很少会遇到需要HRTB的场景,而且即使遇到了我们还有一个神奇的语法糖相助。
下一章:Rust 子类型和变性
子类型是类型之间的一种关系,可以让静态类型语言更加地灵活自由。理解这一概念最简单的方法就是参考一些支持继承特性的语言。比如说一个Animal类型有一个eat()方法,Cat类型继承了Animal并且添加了一个meow ...
AI 中文社