Я хочу переместить элементы HashSet [0] в HashSet [1], ошибка [E0502]: нельзя заимствовать hsets как изменяемые, потому что он также заимствован как неизменяемый - PullRequest
0 голосов
/ 07 мая 2020

Я хочу переместить элементы HashSet [0] в HashSet [1]:

Проект 1: напрямую remove () insert ()

ошибка, невозможно выполнить ie.

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 ve c

правильно, но нужна дополнительная память! на самом деле мой размер данных hset превышает 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 ve c имеет миллионы элементов. так что может быть не лучший способ. спасибо, молоток уступи дорогу!

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);
}

1 Ответ

0 голосов
/ 07 мая 2020

правильно, но в моем hsets ve c миллионы элементов. так что может быть не лучший способ. спасибо

Методы split* (split_at, split_first, split_last и их изменяемые варианты) просто возвращают фрагменты и ссылки, они выполняются в постоянное время, они не копируют ничего, и они определенно не выделяются, поэтому размер ve c на самом деле не имеет значения.

Если у вас есть 10 элементов ve c и разделены посередине, он создаст два среза, которые относятся к исходному вектору и имеют длину 5 и 5, если ваш вектор имеет 10 миллионов элементов, срезы будут иметь длину 5000000 и 5000000. Фактической разницы не имеет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...