显示页面讨论过去修订反向链接回到顶部 本页面只读。您可以查看源文件,但不能更改它。如果您觉得这是系统错误,请联系管理员。 ====== 引用、借用与生命周期 ====== ===== 引用和借用 ===== **引用(Reference)** 允许在不转移所有权的情况下访问值。创建引用称为**借用(Borrowing)**。 ==== 不可变引用 ==== <code rust> fn main() { let s = String::from("hello"); fn len(s: &String) -> usize { s.len() // 借用 s,不拥有所有权 } // s 没有释放 let length = len(&s); println!("'{}' 的长度是 {}", s, length); // s 仍然可用 } </code> **规则**:不可变引用可同时有多个。 <code rust> fn main() { let s = String::from("hello"); let r1 = &s; let r2 = &s; // 多个不可变引用 OK println!("{}, {}", r1, r2); } </code> ==== 可变引用 ==== <code rust> fn main() { let mut s = String::from("hello"); fn change(s: &mut String) { s.push_str(", world"); } change(&mut s); println!("{}", s); // "hello, world" } </code> **规则**:同一时间只能有一个可变引用。 <code rust> fn main() { let mut s = String::from("hello"); let r1 = &mut s; // let r2 = &mut s; // 编译错误:不能同时有两个可变引用 println!("{}", r1); } </code> ==== 引用规则总结 ==== * 同一个作用域中,一个值可以有多个不可变引用(''&T'') * 同一个作用域中,一个值只能有一个可变引用(''&mut T'') * 可变引用和不可变引用不能共存 * 引用必须始终有效(不会出现悬垂引用) <code rust> fn main() { let mut s = String::from("hello"); let r1 = &s; // OK let r2 = &s; // OK // let r3 = &mut s; // 编译错误:已有不可变引用 println!("{}, {}", r1, r2); // r1 和 r2 不再使用 let r3 = &mut s; // 现在 OK r3.push_str("!"); println!("{}", r3); } </code> ===== 字符串切片(Slice) ===== 切片是对集合一部分的引用: <code rust> fn main() { let s = String::from("hello world"); let hello = &s[0..5]; // "hello" let world = &s[6..11]; // "world" println!("{}, {}", hello, world); } </code> ==== 字符串切片类型 &str ==== <code rust> fn main() { let s = String::from("hello world"); // 取前5个字符 let slice1 = &s[..5]; // 等同于 &s[0..5] let slice2 = &s[6..]; // 等同于 &s[6..len] let slice3 = &s[..]; // 整个字符串 println!("{} {} {}", slice1, slice2, slice3); } </code> ==== 数组切片 ==== <code rust> fn main() { let arr = [1, 2, 3, 4, 5]; let slice = &arr[1..3]; // [2, 3] println!("{:?}", slice); } </code> ===== 生命周期简介 ===== 生命周期(Lifetimes)确保引用始终有效。多数情况下编译器可以自动推断。 ==== 生命周期注解语法 ==== <code rust> // 'a 是生命周期参数,标明 x 和 y 必须活得一样长 fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x } else { y } } fn main() { let s1 = String::from("长字符串"); let s2 = String::from("短"); let result = longest(&s1, &s2); println!("较长的: {}", result); } </code> ==== 结构体中的生命周期 ==== <code rust> struct Excerpt<'a> { part: &'a str, // 结构体包含引用时必须标注生命周期 } fn main() { let novel = String::from("很久很久以前..."); let first = novel.split('.').next().expect("没有找到"); let excerpt = Excerpt { part: first }; println!("{}", excerpt.part); } </code> ==== 静态生命周期 ==== '''static'' 生命周期在整个程序运行期间有效: <code rust> // 字符串字面量有 'static 生命周期 let s: &'static str = "我存在于整个程序运行期间"; </code> ===== 本章小结 ===== * 引用允许访问值而不转移所有权 * 同一时间要么多个不可变引用,要么一个可变引用 * 切片是对集合部分元素的引用 * 生命周期注解确保引用不会悬垂 * ''&'static'' 表示整个程序都有效的引用 登录 Detach Close 该主题尚不存在 您访问的页面并不存在。如果允许,您可以使用创建该页面按钮来创建它。 rust/引用借用与生命周期.txt 最后更改: 2026/06/15 15:43由 张叶安 登录