跳至内容
张叶安的小站
用户工具
登录
站点工具
搜索
工具
显示页面
过去修订
反向链接
最近更改
媒体管理器
网站地图
登录
>
最近更改
媒体管理器
网站地图
您的足迹:
rust:第十四章生命周期
本页面只读。您可以查看源文件,但不能更改它。如果您觉得这是系统错误,请联系管理员。
====== 第十四章 生命周期 ====== ===== 14.1 为什么需要生命周期 ===== Rust需要在编译时确保所有引用都是有效的。生命周期就是用来追踪引用的有效范围的。 **核心问题:** 编译器如何知道引用是否指向有效的数据? <code rust> { let r; // ---------+-- 'a // | { // | let x = 5; // -+-- 'b | r = &x; // | | } // -+ | // | println!("r: {}", r); // | } // ---------+ </code> 这段代码编译失败,因为r的生命周期'a比x的生命周期'b长。 ===== 14.2 生命周期标注语法 ===== ==== 标注规则 ==== * 以'开头,通常小写且简短,如'a、'b * 放在&后面,如&'a i32 * 只是描述引用之间的关系,不改变实际生命周期 ==== 示例 ==== <code rust> &i32 // 引用 &'a i32 // 带有显式生命周期的引用 &'a mut i32 // 带有显式生命周期的可变引用 </code> ===== 14.3 函数中的生命周期 ===== ==== 生命周期省略规则 ==== Rust有**生命周期省略规则**,在简单情况下自动推断: 1. 每个引用参数都有自己的生命周期 2. 如果只有一个输入生命周期,它赋给所有输出生命周期 3. 如果有多个输入生命周期,但一个是&self或&mut self,self的生命周期赋给输出 ==== 显式标注示例 ==== <code rust> // 编译错误:编译器无法推断返回值的生命周期 fn longest(x: &str, y: &str) -> &str { if x.len() > y.len() { x } else { y } } </code> 正确写法: <code rust> fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x } else { y } } </code> **含义:** 返回的引用与x和y中生命周期较短的那个相同。 ==== 使用示例 ==== <code rust> fn main() { let string1 = String::from("long string is long"); { let string2 = String::from("xyz"); let result = longest(string1.as_str(), string2.as_str()); println!("最长的字符串是{}", result); } } </code> ==== 错误使用示例 ==== <code rust> fn main() { let string1 = String::from("long string is long"); let result; { let string2 = String::from("xyz"); result = longest(string1.as_str(), string2.as_str()); } println!("最长的字符串是{}", result); // 错误!string2已失效 } </code> ===== 14.4 结构体中的生命周期 ===== ==== 含引用的结构体 ==== 如果结构体包含引用,必须标注生命周期: <code rust> struct ImportantExcerpt<'a> { part: &'a str, } fn main() { let novel = String::from("Call me Ishmael. Some years ago..."); let first_sentence = novel.split('.').next().expect("找不到."); let i = ImportantExcerpt { part: first_sentence, }; println!("{}", i.part); } </code> **含义:** ImportantExcerpt的实例不能比part中的引用活得更长。 ===== 14.5 生命周期的省略 ===== ==== 规则1:每个引用参数有自己的生命周期 ==== <code rust> fn foo<'a>(x: &'a i32) // 一个参数 fn foo<'a, 'b>(x: &'a i32, y: &'b i32) // 两个参数 </code> ==== 规则2:单个输入生命周期赋给输出 ==== <code rust> fn foo<'a>(x: &'a i32) -> &'a i32 // 省略写法:fn foo(x: &i32) -> &i32 </code> ==== 规则3:&self的生命周期赋给输出 ==== <code rust> impl<'a> ImportantExcerpt<'a> { fn level(&self) -> i32 { // 省略写法 3 } } </code> ===== 14.6 静态生命周期 ===== **'static**表示整个程序运行期间都有效。 <code rust> let s: &'static str = "我有静态生命周期"; </code> **注意:** * 字符串字面量有'static生命周期 * 不要盲目使用'static来解决生命周期错误 * 通常意味着设计问题 ===== 14.7 泛型类型参数、Trait Bound和生命周期 ===== <code rust> use std::fmt::Display; fn longest_with_an_announcement<'a, T>( x: &'a str, y: &'a str, ann: T, ) -> &'a str where T: Display, { println!("公告!{}", ann); if x.len() > y.len() { x } else { y } } </code> ===== 14.8 生命周期实践 ===== ==== 返回引用时的生命周期 ==== <code rust> struct Parser<'a> { content: &'a str, } impl<'a> Parser<'a> { fn new(content: &'a str) -> Self { Parser { content } } fn first_word(&self) -> &'a str { self.content.split_whitespace().next().unwrap_or("") } } </code> ==== 多个生命周期 ==== <code rust> fn split<'a, 'b>(input: &'a str, delimiter: &'b str) -> Vec<&'a str> { input.split(delimiter).collect() } </code> ===== 练习题 ===== ==== 练习题14.1:修复生命周期错误 ==== <code rust> fn get_first_word(s: &str) -> &str { s.split_whitespace().next().unwrap_or("") } fn main() { let text = String::from("hello world"); let word = get_first_word(&text); println!("{}", word); } </code> **答案:** 使用生命周期省略规则即可,不需要显式标注。 ==== 练习题14.2:实现包含引用的结构体 ==== <code rust> struct Config<'a> { filename: &'a str, content: &'a str, } impl<'a> Config<'a> { fn new(filename: &'a str, content: &'a str) -> Self { Config { filename, content } } fn display(&self) { println!("文件:{}", self.filename); println!("内容:{}", self.content); } } fn main() { let filename = "config.txt"; let content = "key=value"; let config = Config::new(filename, content); config.display(); } </code> ===== 本章小结 ===== 本章学习了Rust的生命周期: * **生命周期的目的**:确保引用总是有效 * **标注语法**:'a、&'a T * **函数生命周期**:返回值与输入参数关联 * **结构体生命周期**:含引用的结构体需要标注 * **省略规则**:简化常见情况的标注 * **'static**:整个程序运行期间有效 生命周期是Rust内存安全保证的重要组成部分,虽然起初难以理解,但掌握后能写出更安全的代码。
rust/第十四章生命周期.txt
· 最后更改:
2026/02/03 19:45
由
127.0.0.1
页面工具
显示页面
过去修订
反向链接
回到顶部