error: cannot borrow ... as immutable because it is also borrowed as mutable

error: cannot borrow ... as immutable because it is also borrowed as mutable

我实例化了一个结构 result 并将其作为 mutable ref 传递给另一个函数,该函数用数据填充该结构。

之后,我将此结构作为 immutable ref 传递给其他函数,以将数据插入数据库。

let mut result = indexer::IndexRefreshResultHolder {
            putlist: Vec::new(),
            dellist: Vec::new(),
        };

indexer::refresh_indeces(&mut new_idx_set, old_idx_set_opt, &mut result);

pg::delete_index_rows(&mut tx, &result.dellist).await?;
pg::insert_index_rows(&mut tx, &result.putlist).await?;

refresh_indeces的签名如下:

pub fn refresh_indeces<'a>(
    new_idx: &'a mut IndexSet,
    old_idx_opt: Option<&'a mut IndexSet>,
    result: &'a mut IndexRefreshResultHolder<'a>,
) -> Result<(), AppError>

该函数从 new_idxold_idx 中获取数据并将其合并到 result.

编译错误: cannot borrow 'result.dellist' as immutable because it is also borrowed as mutable。 'result.putlist'.

相同

我知道,由于结构是 mutable borrowedrefresh_indeces,因此无法确定数据会在之后发生变化。

我现在的问题是:“我怎样才能让编译器明白,在调用 refresh_indeces 之后 result 没有改变”或者换句话说:“result在作为 mutable ref?

传递一次后再次作为 immutable ref 传递

谢谢你的帮助。

Playground

只需使用一个新范围,以便在需要使用其他引用之前删除 &mut


let mut result = indexer::IndexRefreshResultHolder {
    putlist: Vec::new(),
    dellist: Vec::new(),
};
{
    indexer::refresh_indeces(&mut new_idx_set, old_idx_set_opt, &mut result);
}
pg::delete_index_rows(&mut tx, &result.dellist).await?;
pg::insert_index_rows(&mut tx, &result.putlist).await?;

编辑:实际上你的生命周期是错误的,因为他们强制延长 &mut 的生命周期。您可以将它们分开:


fn refresh_indeces<'a, 'b, 'c>(
    new_idx: &'a mut IndexSet,
    old_idx_opt: Option<&'a mut IndexSet>,
    result: &'b mut IndexRefreshResultHolder<'a>,
) -> Result<(), std::io::Error>

Playground

此外,您正在 playground 中创建一些需要修复的临时引用。在那之后,另一批关于所有权的修复也会出现

通过替换切片解决了它:

result.dellist.extend(old_idx.rows[i_old..].to_vec().iter());

使用迭代器:

for row in old_idx.rows.iter().skip(i_old) {
    result.dellist.push(row);
}