Rust 中神秘的单引号:引号标识符背后隐藏着什么?

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

单引号背后隐藏着什么?认识 Rust 中的生命周期(lifetime)



如果你曾经打开过 Rust 代码,看到过类似 &'a str 或 fn foo<'a>() 这样奇怪的结构,那么你肯定问过自己:“这些单引号到底是什么?”你不是一个人——这个问题在 Stack Overflow 上获得了数千次浏览,并成为初学者的真正难题。



今天,我们将一劳永逸地弄清楚这些神秘的符号。剧透:单引号背后隐藏着 Rust 最强大的概念之一——生命周期(lifetime)。是的,它并没有看起来那么可怕!



在这篇文章中,我不仅会讲解语法,还会告诉你如何正确阅读和使用带单引号的标识符。我们开始吧!



带单引号的标识符:不仅仅是装饰



在 Rust 中,以单引号开头的标识符(例如 'a、'static、'b)是生命周期注解。它们不会影响变量实际存活多久,而是告诉编译器不同引用之间生命周期的关系。



想象一下,你是一名侦探,而 Rust 编译器是你的助手。你说:“这两个引用必须存活同样长的时间”,并用标签 'a 标记它们。编译器会检查你是否违反了这条规则。如果违反了,你会在编译阶段收到错误,而不是在运行时。



为什么它们看起来是这样的?



使用单引号的语法并非偶然。在 Rust 中,单引号用于表示标签(labels)——这是一种为时间段命名的“名称”。这种方法在其他语言中也有出现,但在 Rust 中,它成为了内存安全系统的关键元素。



以下是一些你会遇到这些标签的例子:



  • fn longest<'a>(x: &'a str, y: &'a str) -> &'a str —— 一个返回引用的函数,该引用的存活时间不超过两个参数。
  • struct Book<'a> { title: &'a str } —— 一个包含具有生命周期引用的结构体。
  • &'static str —— 对静态字符串的引用,它在整个程序运行期间都存在。


如何阅读和理解生命周期?



让我们分析几个真实的代码示例。它们将帮助你不再害怕单引号,并开始使用它们。



示例 1:具有一个生命周期的函数



假设我们编写一个函数,返回两个字符串中较长的一个:



fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {    if x.len() > y.len() { x } else { y }}

fn main() { let string1 = String::from("hello"); let result; { let string2 = String::from("world"); result = longest(&string1, &string2); } // println!("{}", result); // 编译错误!}


这里发生了什么?我们告诉编译器:“结果的存活时间不会超过 x 和 y 两者中较短的那个”。当 string2 离开作用域时,result 变得无效。编译器看到了这一点,并阻止我们搬起石头砸自己的脚。



示例 2:包含引用的结构体



初学者经常尝试在结构体中存储引用,并遇到错误。解决方案是显式指定生命周期:



#[derive(Debug)]struct Book<'a> {    title: &'a str,    author: &'a str,}

fn main() { let title = String::from("The Rust Programming Language"); let author = String::from("Steve Klabnik"); let book = Book { title: &title, author: &author, }; println!("{:?}", book);}


这里的 'a 意味着 title 和 author 必须至少与结构体 Book 本身存活一样长的时间。如果你试图删除

博客

书籍推荐