How to call Vec<>::append() for a moved Vec<> argument?

Viewed 152

I'm writing a simple builder. I'd like to have a builder method consume self, and also consume a Vec<Node> and append it to a Vec<Node> that self already owns.

I have this method:

pub fn with_nodes(mut self, mut nodes: Vec<Node>) -> Graph {
    self.nodes.append(&nodes);
    self
}

nodes is a non-reference because I want to consume it, and it's mut because Vec<>::append() mutates its argument.

Problem is, I get:

46 |             self.nodes.append(&nodes);
   |                               ^^^^^^ types differ in mutability
   |
   = note: expected mutable reference `&mut Vec<Node>`
                      found reference `&Vec<Node>`

How come that nodes is immutable, as it's explicitly marked mut? How else can I make the argument a locally mutable Vec?

1 Answers

The issue isn't that nodes is not mutable, you need to explicitly pass a mutable reference to it as well:

pub fn with_nodes(mut self, mut nodes: Vec<Node>) -> Graph {
    self.nodes.append(&mut nodes);
    self
}

You can also avoid mutability:

pub fn with_nodes(mut self, nodes: Vec<Node>) -> Graph {
    self.nodes.extend(nodes.drain());
    self
}

Another tip, instead of repeating the type name in the return type, you can use Self instead of Graph. This makes refactoring easier.

Related