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
forl
和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
返回指向向量的指针?)!