不能借用不可变的“值”,因为它也借用为可变的

use*_*862 3 rust

我发现很多关于不可变到可变的问题,但不太确定我在这段代码中做错了什么。

我收到的错误是:“不能values作为不可变的借用,因为它也作为可变的借用”

fn modify_vec_get_slice(values: &mut Vec<i32>) -> &[i32] {
    // Modify "values" in some way
    values.push(5);

    // Return a slice into "values" (dummy code)
    values.split_at(values.len() / 2).1
}

fn use_slice(slice: &[i32]) {
    // Do something immutably with the slice
}

fn use_vec(values: &Vec<i32>) {
    // Do something immutably with the vec
}

fn main() {
    let mut values = vec![1, 2, 3, 4];

    let slice = modify_vec_get_slice(&mut values); // use values mutably

    use_vec(&values); // Error here is "&values" underlined in red, even though "values" is used immutably

    use_slice(slice); // use slice immutably (which refers to the vec?). Uncommenting this line fixes the error
}

Run Code Online (Sandbox Code Playgroud)

当我可以使用 &values (也是一个不可变引用)时,为什么我不能使用切片(一个不可变引用)?当我到达其他函数时,“modify_vec_get_slice”中使用的可变引用肯定已经结束了吗?

cdh*_*wie 7

问题是slice有效地拥有 上的可变借用values。对您来说,情况似乎不应该如此,因为返回的引用modify_vec_get_slice()是不可变的,但该不可变引用与赋予该函数的可变引用的生命周期相关联。如果我们通过生命周期省略显式指定编译器假定的生命周期,这一点就会变得清晰:

fn modify_vec_get_slice<'a>(values: &'a mut Vec<i32>) -> &'a [i32] {
Run Code Online (Sandbox Code Playgroud)

返回的引用只允许与可变借用一样长地存在,因此slice也延长了扩展可变借用的生命周期。在这种情况下,不会发生任何类型的隐含“引用类型降级”。

解决此问题的最简单方法是将函数分为两部分,一种采用可变引用并执行突变,另一种采用不可变引用并计算切片的边界并返回它。

进一步阅读: