gpt4 book ai didi

在闭包中使用 split_at_mut 出现 Rust 错误 E0495

转载 作者:行者123 更新时间:2023-11-29 08:07:48 25 4
gpt4 key购买 nike

我遇到了“错误[E0495]:由于需求冲突,无法推断出 autoref 的适当生命周期”,这个简单的函数:

fn assign_split_at_mut<'a, 'b, T>(s: &'b mut &'a mut [T], mid: usize) -> &'a mut [T] {
let (x, y) = (*s: &'a mut [T]).split_at_mut(mid);
*s = y;
x
}

我写了一个playpen example包括确实有效的 split_at_mut 的这个 unsafe 变体。

fn assign_split_at_mut_unsafe<'a, T>(s: &mut &'a mut [T], mid: usize) -> &'a mut [T] {
let len = (*s: &'a mut [T]).len();
let ptr = (*s: &'a mut [T]).as_mut_ptr();

unsafe {
use std::slice::from_raw_parts_mut;
assert!(mid <= len);
*s: &'a mut [T] = from_raw_parts_mut(ptr.offset(mid as isize), len - mid);
from_raw_parts_mut(ptr, mid)
}
}

其实我想大致这样写:

pub fn slice_header<'a>(&'static self, mut header: &'a mut [u8])
-> MyResult<HeaderRefs<'a>>
{
// ...
let take = |l: usize| -> &'a mut [u8] {
let (x,y) = header.split_at_mut(l);
header = y; x
};
let hr = HeaderRefs {
params: self,
alpha: array_mut_ref![take(32),0,32],
gamma: array_mut_ref![take(16),32,16],
beta: take(self.beta_length as usize),
surb_log: take(self.surblog_length as usize),
surb: take(self.surb_length()),
};
// ...
Ok(hr)
}

我相信如果我简单地写出一堆就可以了

let (alpha,header) = header.split_at_mut(32);
let (gamma,header) = header.split_at_mut(16);
// ...

如果我将它们放入一个数组中,也许它会起作用。我无法让它与闭包一起使用,这看起来会更干净。

最佳答案

这是一个借用问题:

fn assign_split_at_mut<'a, 'b, T>(s: &'b mut &'a mut [T], mid: usize) -> &'a mut [T] {
let (x, y) = (*s: &'a mut [T]).split_at_mut(mid);
*s = y;
x
}

具体来说,split_at_muts ,所以你不能分配给s而它是借来的。

要理解这个问题,假设我们在这里讨论向量,使用 s: &mut Vec<T> : 你可以先从 Vec 借一片然后使用 s对其进行变异。

这就是为什么 Rust 指定借用整个访问路径,而不仅仅是叶子。


好的,那现在呢?

正如@nox 所提到的,解决方案是“跳舞”:

  • 移动 &'a mut [T] 的所有权来自 s到局部变量
  • 借用这个局部变量
  • 分配给s

这样,借用检查器就安抚了,因为它知道修改 s不能影响局部变量及其借用。

有多种方法可以将所有权移出 &mut X根据情况,一些常见的方式是:

  • std::mem::replace ,
  • std::mem::swap ,
  • Option::take如果X是一个 Option ,
  • ...

在你的例子中,replace越简单。 @nox 提供的解决方案非常简单:

fn reserve<'heap, T>(heap: &mut &'heap mut [T], len: usize) -> &'heap mut [T] {
let tmp: &'heap mut [T] = ::std::mem::replace(&mut *heap, &mut []);
let (reserved, tmp) = tmp.split_at_mut(len);
*heap = tmp;
reserved
}

关于在闭包中使用 split_at_mut 出现 Rust 错误 E0495,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42162151/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com