视频:解释最复杂的 Rust 语言特性
在本视频中,我们将通过尝试定义一个看似简单的 trait 来探索 Rust 的一些最复杂的语言特性。
时间戳:
00:00 第一个版本 trait
00:20 静态调度与动态调度
02:24 Dyn compatibility & Impl Trait 语法
3:36 异步 Rust
5:22 Boxed futures
07:00 Pinning & Unpin
11:59 发送和同步特性
16:55 生命周期
28:20 最终版本的 trait
28:58 async_trait 宏
观看:https://youtu.be/9RsgFFp67eo
文章《Simple Bidirectional Type Inference》
主要介绍了 双向类型推导(Bidirectional Type Inference) 的原理及其在简单类型 Lambda 演算(STLC)中的实现。
通过将类型检查拆解为“推导”和“检查”两个互补的过程,降低了实现现代编程语言类型系统的复杂度。
什么是双向类型推导? 与 Rust 或 Haskell 使用的 Hindley-Milner (HM) 算法不同,双向类型推导将类型检查分为两个方向:
- 推导/合成 (Inference/Synthesis,
=>):从项(Term)中提取出它的类型。 - 检查 (Checking,
<=):验证一个项是否符合给定的类型。
优点:实现简单、报错信息更精准(避免了 HM 算法中复杂的“合一/unification”错误)。 缺点:在某些情况下需要用户手动添加类型标注(Annotation)。
核心规则转换逻辑 文章介绍了如何将传统的类型系统规则(Pfenning 方法)转换为双向规则:
- 引入规则(Introduction rules):通常设为检查模式。例如,当你创建一个函数(Lambda)时,你通常已经知道预期的函数类型。
- 消除规则(Elimination rules):通常设为推导模式。例如,在函数调用(Application)时,你需要先从函数项中推导出它的类型,才能知道它接收什么参数。
- 变量与标注:变量通过查表直接推导;类型标注则将检查模式转为推导模式。
具体规则定义
- 布尔值 (
True/False):检查模式。验证项是否为Bool。 - Lambda 抽象 (
λx. L):检查模式。如果已知预期类型是A -> B,则将x:A加入环境,检查L是否符合B。 - 函数应用 (
L M):推导模式。先推导L的类型A -> B,然后检查M是否符合A,最终推导出结果类型B。 - 类型标注 (
(L : A)):推导模式。手动告诉编译器类型,编译器检查L是否符合A后,将其作为推导结果。
Rust 实现要点:
作者提供了 Rust 的代码示例,展示了如何通过两个互相递归的函数 infer 和 check 来实现该算法:
infer函数:返回Result<Type, TypeError>。check函数:返回Result<(), TypeError>(只需验证是否匹配)。- 错误处理:由于方向明确,当类型不匹配时,可以直接指出是“参数类型不匹配”还是“缺少标注”。
结论与思考
- 易用性:虽然看似需要更多标注,但在实际语言设计中(如 Rust/C),如果强制要求顶层函数必须有类型签名,那么在函数体内部几乎不需要额外的标注。
- 扩展性:文章最后留了一个关于
if-then-else的练习。通常if语句会被实现为检查模式,以减少对分支类型的推导压力。
阅读:https://ettolrach.com/blog/bidirectional_inference.html
ffmpreg:用 Rust 完全重写 FFmpeg
阶段:处于早期实验阶段
已实现功能:
- 基础的位流(Bitstream)读写工具。
- 初步的容器格式支持(如 MP4、Matroska 的部分解析)。
- 一些基础的音频/视频数据结构定义。
架构设计:项目试图将组件高度模块化,使其不仅可以作为 CLI 工具使用,也可以作为库集成到其他 Rust 项目中。
为什么要用 Rust 重写?:
- 内存安全性:FFmpeg 是用 C 和汇编编写的,长期以来饱受缓冲区溢出等内存安全漏洞的困扰。Rust 的所有权模型可以从根本上消除这些问题。
- 现代并行化:利用 Rust 的并发特性(如 Rayon 或 Tokio),更安全、更高效地实现多线程编解码。
- 代码可维护性:C 语言的代码库庞大且复杂,重构困难。Rust 提供了更好的模块化工具和包管理(Cargo)。
- 消除冗余:FFmpeg 包含大量过时的、几乎无人使用的旧格式支持。
ffmpreg倾向于构建一个更现代、更精简的核心。
社区讨论:
- 支持派:
- 认为这是 Rust 生态中缺失的重要一环(目前 Rust 开发者大多依赖封装 C 库的
ffmpeg-sys)。 - 对安全性提升表示极大的期待,尤其是在处理不可信的在线视频上传时。
- 认为这是 Rust 生态中缺失的重要一环(目前 Rust 开发者大多依赖封装 C 库的
- 怀疑/挑战派:
- 工作量巨大:FFmpeg 拥有数百万行代码和高度优化的手工汇编(SIMD),仅凭个人或小团队很难在性能上追平。
- 性能瓶颈:视频处理极度依赖硬件加速和特定的 CPU 指令集。Rust 虽然性能强劲,但在底层手动优化(如 AVX-512, NEON)方面仍需大量投入。
- 兼容性:FFmpeg 的强大在于它能处理几乎任何“坏掉的”或非标的视频文件,这种长年积累的鲁棒性很难被快速复制。
总结:ffmpreg 是一个极具野心的项目,旨在解决多媒体处理领域的安全痛点。
- 如果你是开发者:目前它还不能替代 FFmpeg,但如果你对 Rust 处理二进制流、媒体协议感兴趣,这是一个非常好的学习和贡献机会。
- 如果你是用户:目前建议继续使用原版 FFmpeg 或基于 C 库封装的 Rust 绑定,因为
ffmpreg距离生产环境可用还有很长的路要走。
仓库:https://github.com/yazaldefilimone/ffmpreg
讨论:https://www.reddit.com/r/rust/comments/1q0maft/introduction_ffmpreg_a_complete_rewrite_of_ffmpeg/
--
From 日报小组 苦瓜小仔
社区学习交流平台订阅:
评论区
写评论还没有评论