对Rust生命周期的常见误解 2021-06-09 00:07:12 Rust最难的部分莫过于lifetime了。 近期在看async-raft源码的过程中,发现了这样的一个定义,其中`'static`给我带来一些疑惑: ``` pub trait AppData: Debug + Clone + Send + Sync + Serialize + DeserializeOwned + 'static {} ``` 难道impl AppData的类型,生成的对象,就不能被释放了,程序运行期间一直在占用内存?思来想去觉得这样的定义不合理,或许我对`'static`的理解有误。 好在网上已经有人对这块做了整理,相比Rust官方文档介绍的更全面些,对于`T: 'static`,表示T即可以是有`'static lifetime`的borrowed type,带有`'static`的生命周期,也可以直接是一个owned type。 ## 对Rust生命周期的常见误解 下面还有一些其他常见误解的总结,内容转载自:<https://github.com/pretzelhammer/rust-blog/blob/master/posts/translations/zh-hans/common-rust-lifetime-misconceptions.md> - `T` 是 `&T` 和 `&mut T` 的超集 - `&T` 和 `&mut T` 是不相交的集合 - `T: 'static` 应当视为 _“`T` 满足 `'static` 生命周期约束”_ - 若 `T: 'static` 则 `T` 可以是一个有 `'static` 生命周期的引用类型 _或_ 是一个所有权类型 - 因为 `T: 'static` 包括了所有权类型,所以 `T` - 可以在运行时动态分配 - 不需要在整个程序运行期间都有效 - 可以安全,自由地修改 - 可以在运行时被动态的 drop - 可以有不同长度的生命周期 - `T: 'a` 比 `&'a T` 更泛化,更灵活 - `T: 'a` 接受所有权类型,内部含有引用的所有权类型,和引用 - `&'a T` 只接受引用 - 若 `T: 'static` 则 `T: 'a` 因为对于所有 `'a` 都有 `'static` >= `'a` - 几乎所有的 Rust 代码都是泛型代码,并且到处都带有被省略掉的泛型生命周期注解e - Rust 生命周期省略规则并不保证在任何情况下都正确 - 在程序的语义方面,Rust 并不比你懂 - 可以试试给你的生命周期注解起一个有意义的名字 - 试着记住你在哪里添加了显式生命周期注解,以及为什么要 - 所有 trait 对象都含有自动推导的生命周期 - Rust 编译错误的提示信息所提出的修复方案并不一定能满足你对程序的需求 - 生命周期在编译时被静态确定 - 生命周期在运行时不能被改变 - Rust 借用检查器假设所有代码路径都能被执行,所以总是选择尽可能短的生命周期赋给变量 - 尽量避免重借用一个独占引用为共享引用,不然你会遇到很多麻烦 - 重借用一个独占引用并不会结束其生命周期,哪怕它自身已经被 drop 掉了 - 每个语言都有其陷阱 🤷 - `for <'a,T> fn()->&'a T` 签名的函数比 `for <T> fn()->&'static T` 签名的函数要更灵活,并且泛用于更多场 ## 附 - 原文[Common Rust Lifetime Misconceptions](https://github.com/pretzelhammer/rust-blog/blob/master/posts/common-rust-lifetime-misconceptions.md) 非特殊说明,均为原创,原创文章,未经允许谢绝转载。 原始链接:对Rust生命周期的常见误解 赏 Prev 关于CDH平台Hive Metastore Server的Canary duration指标 Next Rust正式入坑