首页 > 解决方案 > 当有一个函数涉及可变/不可变引用作为具有(嵌套)生命周期的参数时,编译器如何处理借用?

问题描述

fn func_vecmut<'a>(v: &'a mut Vec<&'a i32>, s: &'a String) {}

fn func_vecmut_fresh_lf<'a, 'b>(v: &'a mut Vec<&'a i32>, s: &'b String) {}

fn func_vec<'a>(v: &'a Vec<&'a i32>, s: &'a String) {}

fn main() {
    let mut v = vec![];
    {
        let s: String = String::from("abc");

        /* Note: Below, only one function call is active at a time, other two commented out */
        func_vecmut(&mut v, &s);          // Understandably, compiler fails this.
        func_vecmut_fresh_lf(&mut v, &s); // Understandably, compiler passes this i.e with fresh lifetime for String.
        func_vec(&v, &s);                 // Why does compiler pass this?
    }
}

func_vecmut(据我了解)中,编译器看到它的生命周期与它所拥有的元素( )String相同。而且由于寿命更长(在块外定义),它将借用扩展到块范围之外(即来世 for ),因此出现以下错误:Veci32vss

error[E0597]: `s` does not live long enough
  --> src/main.rs:13:30
   |
13 |         func_vecmut(&mut v, &s);          // Understandably, compiler fails this.
   |                              ^ borrowed value does not live long enough
...
16 |     }
   |     - `s` dropped here while still borrowed
17 | }
   | - borrowed value needs to live until here

可以通过赋予String参数一个新的生命周期来解决这个问题(请参阅 参考资料func_vecmut_fresh_lf)。

但是,为什么编译不会失败func_vec(&v, &s)呢?唯一的区别是&mut Vec。这与不可变引用是Copy,而可变引用不是这一事实有关吗?如果是,怎么做?函数体是空的,编译器在这里推断什么?

标签: rustlifetimeborrow-checker

解决方案


推荐阅读