结论:当结构体(或枚举)的字段持有引用时,必须在类型上声明生命周期参数,如 struct Foo<'a> { r: &'a str },含义是"该结构体实例不能比它借用的数据活得更久"——结构体本身成为被借用数据的一个借用方。
展开:编译器要保证实例存活期间所有引用字段都有效,因此实例的生命周期受 'a 约束;impl 块同样要带参数:impl<'a> Foo<'a>。设计取舍:持有引用的结构体零拷贝、无分配(如解析器直接切片输入缓冲),但会让类型"感染"生命周期,在存入容器、跨函数传递、异步任务中处处受限;持有所有权的字段(String 代替 &str)更灵活但多一次分配。工程建议:短期视图/解析输出用引用字段,长期存储与跨线程数据用拥有型字段。易错点:方法返回字段引用时省略规则三默认绑定到 &self,语义正确时可直接省略。追问方向:自引用结构体(字段引用同结构体另一字段)为何不行?移动结构体会使内部指针失效,需 Pin 或 ouroboros 等方案。
struct Parser<'a> { input: &'a str, pos: usize }
impl<'a> Parser<'a> {
fn rest(&self) -> &'a str { &self.input[self.pos..] }
}
let text = String::from("abc");
let p = Parser { input: &text, pos: 0 }; // p 不得比 text 活得久