You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

String::push_str与Vec::push的生命周期约束差异及报错原因

Rust生命周期差异问题解析

代码示例

struct V<'a> {
    s: &'a mut String,
    v: Vec<&'a String>
}

impl<'a, 'b> V<'a> {
    pub fn set(&mut self, s: &'b String){
        // self.s = s;
        self.s.push_str(s);
        self.v.push(s);
    }
}

编译错误信息

error: lifetime may not live long enough
  --> src/main.rs:68:9
   |
64 | impl<'a, 'b> V<'a> {
   |      --  -- lifetime `'b` defined here
   |      |
   |      lifetime `'a` defined here
...
68 |         self.v.push(s);
   |         ^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
   |
   = help: consider adding the following bound: `'b: 'a`

问题

上述代码中,self.s.push_str(s);可以正常编译,但self.v.push(s);触发了生命周期错误。两者调用时传入的参数形式类似(均为&mut self和一个引用参数),为何会出现这种差异?我阅读了NLL相关文档,但仍感到困惑。

核心原因:引用的使用方式差异

两者的本质区别在于是否将传入的引用长期存储到结构体中:

  • self.s.push_str(s)的调用逻辑
    push_str的方法签名是fn push_str(&mut self, string: &str),它只是临时借用s的内容来追加到self.s里,方法执行完成后就不再依赖s的引用。编译器只需要保证push_str执行期间s是有效的,不需要s的生命周期'b长于结构体的'a。

  • self.v.push(s)的调用逻辑
    self.v的类型是Vec<&'a String>,这意味着它存储的所有引用必须拥有至少和结构体生命周期'a一样长的存活时间。当你把&'b String类型的s推入这个向量时,编译器必须确保'b的生命周期不短于'a——否则结构体还存在时,s引用的字符串可能已经被销毁,产生悬垂引用,这是Rust的安全规则绝对禁止的。

修复方案

给生命周期'b添加'b: 'a的约束,明确告知编译器传入的s的生命周期至少和结构体的'a一样长,代码即可正常编译:

impl<'a, 'b: 'a> V<'a> {
    pub fn set(&mut self, s: &'b String){
        self.s.push_str(s);
        self.v.push(s);
    }
}

内容的提问来源于stack exchange,提问作者杨尚山

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 11:05:10