Rust 为什么Vec<;T>;::split_at_mut借用作用域其余部分的向量?

Rust 为什么Vec<;T>;::split_at_mut借用作用域其余部分的向量?,rust,borrow-checker,Rust,Borrow Checker,Vec有两种方法: fn push(&mut self, value: T) fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) 它们都采用向量的可变引用。但借款的范围似乎有所不同,例如: fn works() { let mut nums: Vec<i64> = vec![1,2,3,4]; nums.push(5); println!("{}"

Vec
有两种方法:

fn push(&mut self, value: T)
fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T])
它们都采用向量的可变引用。但借款的范围似乎有所不同,例如:

fn works() {
    let mut nums: Vec<i64> = vec![1,2,3,4];
    nums.push(5);
    println!("{}", nums.len());
}

fn doesnt_work() {
    let mut nums: Vec<i64> = vec![1,2,3,4];
    let (l,r) = nums.split_at_mut(2);
    println!("{}", nums.len());
}

fn also_works() {
    let mut nums: Vec<i64> = vec![1,2,3,4];
    let _ = nums.split_at_mut(2);
    println!("{}", nums.len());
}
fn工程(){
让mut nums:Vec=Vec![1,2,3,4];
推(5);
println!(“{}”,nums.len());
}
fn不工作(){
让mut nums:Vec=Vec![1,2,3,4];
设(l,r)=在(2)处拆分的数值;
println!(“{}”,nums.len());
}
fn还_工程(){
让mut nums:Vec=Vec![1,2,3,4];
设u=nums.split_在_mut(2);
println!(“{}”,nums.len());
}

不起作用
函数不编译,表示在
nums
上已经有一个可变的借用,并且它结束并结束函数。如果我忽略从
split\u at_mut

返回的值,问题就会消失,
nums
的借用不起作用
只要变量
l
r
存在,因为向量中的值(以及向量本身)就存在从字面上说是借来的,现在只能通过
l
r
访问

您可以通过将
let
for
l
r
放在一个结束的范围内,从而使借用也结束,从而看到这种效果。例如,此代码工作正常,但如果您尝试移动
println在范围内(在花括号内),则它将失败:

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

    {
        let (l, r) = nums.split_at_mut(2);
        //println!("{}", nums.len()); //println! will fail here
    }

    println!("{}", nums.len());
}

在您的
还可以使用
示例中,您没有对结果进行任何处理,因此借用会立即丢失。基本上,编译器可以看到,您无法通过方法的结果访问向量,因此您可以通过原始向量自由访问它们。

让我回答我自己的问题,因为我真正缺少的是生命周期。此代码编译:

fn maybe_use<'a, 'b>(v1: &'a mut Vec<i64>, v2: &'b mut Vec<i64>) -> &'a mut Vec<i64> {
    v1
}

fn main() {
    let mut nums1: Vec<i64> = vec![1,2,3,4];
    let mut nums2: Vec<i64> = vec![1,2,3,4];

    let ret = maybe_use(&mut nums1, &mut nums2);

    println!("{}", nums2.len());
}
fn可能使用(v1:&'a mut-Vec,v2:&'b mut-Vec)->&'a mut-Vec{
v1
}
fn main(){
设mut nums1:Vec=Vec![1,2,3,4];
设mut nums2:Vec=Vec![1,2,3,4];
让ret=maybe_使用(&mut nums1,&mut nums2);
println!(“{}”,nums2.len());
}
因为maybe_use的返回类型表明引用来自第一个参数。如果我们将
v2
更改为使用
'a
生存期,
main
将停止编译,因为传递给
的两个向量都可能被认为是借用的。如果我们完全忽略生存期,编译器将发出以下错误:

此函数的返回类型包含借用值,但 签名没有说明它是从
v1
还是
v2


因此,最初让我惊讶的是(编译器如何知道
split_at_mut
返回指向向量的指针?)!