我想将HashSet [0]的元素移动到HashSet [1],错误[E0502]:不能借用`hsets`可变,因为它也借作不可变的借用

问题描述 投票:0回答:1

我想将HashSet [0]的元素移动到HashSet [1]:

项目1:直接将remove()insert()

错误,无法满足。

use std::collections::HashSet;

fn main() {
    let mut hsets = vec![];

    // first set
    hsets.push(HashSet::new());
    hsets[0].insert("a1");
    hsets[0].insert("a2");

    // second set
    hsets.push(HashSet::new());
    hsets[1].insert("b1");
    hsets[1].insert("b2");

    // I want move elements of HashSet[0] to HashSet[1]
    for &v in hsets[0].iter() {
        hsets[0].remove(v);
        hsets[1].insert(v);
    }

    dbg!(&hsets);
}
error[E0502]: cannot borrow `hsets` as mutable because it is also borrowed as immutable
  --> src/main.rs:17:9
   |
16 |     for &v in hsets[0].iter() {
   |               ---------------
   |               |
   |               immutable borrow occurs here
   |               immutable borrow later used here
17 |         hsets[0].remove(v);
   |         ^^^^^ mutable borrow occurs here

error[E0502]: cannot borrow `hsets` as mutable because it is also borrowed as immutable
error: aborting due to 2 previous errors

项目2:使用tmp vec

正确,但是需要额外的内存!实际上,我的hsets数据大小超过56G内存!所以我希望不要增加额外的内存。

use std::collections::HashSet;

fn main() {
    let mut hsets = vec![];

    // first set
    hsets.push(HashSet::new());
    hsets[0].insert("a1");
    hsets[0].insert("a2");

    // second set
    hsets.push(HashSet::new());
    hsets[1].insert("b1");
    hsets[1].insert("b2");

    let mut arr = vec![];
    for &v in hsets[0].iter() {
        arr.push(v);
    }
    for v in arr {
        hsets[0].remove(v);
        hsets[1].insert(v);
    }

    dbg!(&hsets);
}

项目3:使用split_at_mut()

正确,但是我的hsets vec具有数百万个元素。因此可能不是一个好方法。谢谢椒盐脆饼让路!

use std::collections::HashSet;

fn main() {
    let mut hsets = vec![];

    // first set
    hsets.push(HashSet::new());
    hsets[0].insert("a1");
    hsets[0].insert("a2");

    // second set
    hsets.push(HashSet::new());
    hsets[1].insert("b1");
    hsets[1].insert("b2");

    dbg!(&hsets);
    assert_eq!(hsets[0].len(), 2);
    assert_eq!(hsets[1].len(), 2);

    // move elements from first set to second set
    let (first, second) = hsets.split_at_mut(1);
    second[0].extend(first[0].drain());

    dbg!(&hsets);
    assert_eq!(hsets[0].len(), 0);
    assert_eq!(hsets[1].len(), 4);
}
rust immutability mutable borrow
1个回答
0
投票

正确,但是我的hsets vec具有数百万个元素。因此可能不是一个好方法。谢谢

split*方法(split_atsplit_firstsplit_last及其可变变体)仅返回切片和引用,它们以固定的时间执行,它们不复制任何内容,并且当然也不会分配,因此vec的大小并不是真正的问题。

如果您有10个元素vec并在中间分割,它将创建两个切片,这些切片引用原始向量,长度为5和5,如果您的向量有1000万个元素,则切片的长度将为5000000和5000000。无实际差异。

© www.soinside.com 2019 - 2024. All rights reserved.