我可以避免使用显式生命周期标识符,改用引用计数(Rc)吗?

8
我正在阅读《Rust Book》,一切都很容易理解(感谢书的作者),直到涉及到lifetimes。我花了一整天的时间阅读了许多关于生命周期的文章,但仍然对正确使用它们非常不确定。
尽管如此,我理解的是,显式生命周期指定符的概念旨在解决悬空引用的问题。我也知道 Rust 有引用计数智能指针(Rc),我相信这与 C++ 中的 shared_ptr 相同,其目的是防止悬空引用。
考虑到那些生命周期对我来说非常可怕,而智能指针对我来说非常熟悉和舒适(我在 C++ 中经常使用它们),我是否可以避免使用生命周期,转而使用智能指针?还是生命周期在 Rust 代码中是不可避免的东西,我必须理解和使用它们?

2
您可以在代码中使用引用计数指针来部分避免生命周期注释。但是,在处理其他人的 crate 时,您不总是能够避免它们(这几乎总是会出现)。更重要的是,您的代码将运行 Rust 的主旨,您将遇到各种不同的复杂问题,这些问题更难以处理。因此,简短的答案可能是“不”。 - Sven Marnach
2
你可以使用引用计数指针 - 但这些实际上只是将生命周期问题从编译时转移到运行时,以方便为代价换取性能。还有一些情况下它们不起作用 - 比如需要独占/可变访问权限的情况。我建议学习使用生命周期而不是依赖引用计数指针 - 它们不同且更难理解,但它们是许多更高级别的Rust概念的基础,你不能长期避免它们。 - apetranzilla
1个回答

8
您是否必须理解并在Rust代码中使用生命周期?
为了阅读现有的Rust代码,您可能不需要理解生命周期。借用检查器理解它们,因此如果编译成功,则正确性无误,您只需查看代码执行的内容即可。
我非常不安全地使用它们正确吗?
关于生命周期注释最重要的一点是它们什么都不做。相反,它们是一种表达引用之间关系的方法。例如,如果函数的输入和输出具有相同的生命周期,则意味着输出包含对输入(或其部分)的引用,因此不允许输出比输入存活时间更长。错误地使用它们意味着您告诉编译器有关引用寿命的信息,而它可以证明这是不正确的,并且会向您发出错误提示,因此没有什么可不安全的!
我能否放弃生命周期,转而使用智能指针?
您可以选择完全避免使用引用,并且到处使用Rc 。您将错过Rust的一个重要特性:生命周期和引用构成了最重要的零成本抽象之一,使Rust同时快速且安全。有些人根本不会尝试使用C / C ++编写的Rust代码,因为人类永远无法确定他们是否已经引入了内存错误。避免使用Rust引用而使用智能指针大多会导致较慢的代码,因为智能指针具有运行时开销。
许多API使用引用。为了使用这些API,您将需要至少了解正在发生的事情。
理解最好的方法就是编写代码,并从有效和无效的代码中形成直觉。 Rust的错误消息非常出色,并将对形成该直觉提供很大帮助。

1
非常感谢!这给了我一些信心和方向,我认为我将进一步尝试去理解生命周期。 - Nurbol Alpysbayev
经过一些休息之后... Peter,你能不能简单地解释一下为什么编译器要求我注释生命周期,即使它可以证明它们的正确性?如果编译器如此聪明,为什么不在没有我的帮助下“注释”它们呢? - Nurbol Alpysbayev
3
两个字:不行。70+字......类型检查器(包括借用检查器)不会超越函数类型边界进行检查。当你编写函数类型签名时,你正在声明一个双方必须遵守的合同,包括函数主体和任何调用者。类型检查器独立地证明了合同的双方都得到了尊重。尊重类型边界是Rust-和大多数其他类型语言-中的主要抽象,打破它会导致脆弱的代码。 - Peter Hall
我不是开发编程语言的专家,但是感觉他们可以通过分析每次调用函数时的参数来进行这种检查(即超越函数边界)。虽然我确定他们在做这件事上会遇到一些技术障碍。无论如何,非常感谢(为了给我花费70多个字的解释:-))易于理解的解释! - Nurbol Alpysbayev
3
@NurbolAlpysbayev 你可能会发现阅读这篇文章有所帮助:为什么在 Rust 中需要明确生命周期? - trent

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接