Anunaki
Anunaki

Reputation: 881

cannot borrow `hsets` as mutable because it is also borrowed as immutable

I want move elements of HashSet[0] to HashSet[1], but always encounter borrowed error: I try using a tmp vec to save the elemetns, but problem still exists:

use std::collections::HashSet;

fn main() {

    let mut hsets = vec![];


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

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

    // tmp vec save hsets[0]: [a1, a2]
    let mut arr = vec![];

    for v in &hsets[0] {
        arr.push(v);
    }

    for v2 in arr {
        hsets[1].insert(v2);
    }
}

Result:

error[E0502]: cannot borrow `hsets` as mutable because it is also borrowed as immutable
  --> src/main.rs:18:9
   |
13 |     for v in &hsets[0] {
   |               ----- immutable borrow occurs here
...
17 |     for v2 in arr {
   |               --- immutable borrow later used here
18 |         hsets[1].insert(v2);
   |         ^^^^^ mutable borrow occurs here

error: aborting due to previous error

Upvotes: 0

Views: 374

Answers (2)

pretzelhammer
pretzelhammer

Reputation: 15115

I'm assuming you don't want to move the HashSets out of the Vec or de-allocate them, in which case you can do this:

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

playground

If you'd like to get a deeper understanding of why your code as-is doesn't compile then read How to get mutable references to two array elements at the same time?.

Upvotes: 1

apatniv
apatniv

Reputation: 1856

Try to be explicit about the type of the Vector like

let mut arr: Vec<&str> = vec![]; // otherwise compiler is interpreting as Vec<&&str>

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=d0b4e82ab1eb12791a18cf6d33ad0ca4

Upvotes: 0

Related Questions