Reputation: 11
My function takes a Vec
of structs as a parameter and places each of it's element into another vector as a new structure field:
fn new(cards: Vec<Card<'t>>) -> Self {
CardsConnection {
edges: cards.iter().map(|c| CardsConnectionEdge {
cursor: c.id.clone(),
node: *c
}).collect::<Vec<CardsConnectionEdge>>()
}
}
I really want a move, so only new vector should own the Card
instances. So since map got a reference, I want do dereference it to move the value, but I got the following error:
error[E0507]: cannot move out of `*c` which is behind a shared reference
--> src/model.rs:74:23
|
74 | node: *c
| ^^ move occurs because `*c` has type `model::Card<'_>`, which does not implement the `Copy` trait
error: aborting due to previous error; 8 warnings emitted
While this non "functional-style" code works fine:
fn new(cards: Vec<Card<'t>>) -> Self {
let mut edges = Vec::<CardsConnectionEdge>::with_capacity(cards.len());
for c in cards {
edges.push(CardsConnectionEdge {
cursor: c.id.clone()
node: c
})
}
CardsConnection {
edges
}
}
but looks a bit clumsy.
It there a way to do the same thing using iterators or some kind of map function? Or what is the idiomatic way of solving this kind of problems?
Upvotes: 1
Views: 834
Reputation: 13578
You are looking for into_iter()
The iter
function iterates over the items by reference, while into_iter
iterates over the items, moving them into a new scope.
So for c in cards {...}
is essentially the same as cards.into_iter().for_each(|c| ... )
. Both move the elements of cards into the ...
scope.
fn new(cards: Vec<Card<'t>>) -> Self {
CardsConnection {
edges: cards
.into_iter()
.map(|c| CardsConnectionEdge {
cursor: c.id.clone(),
node: c,
})
.collect(),
}
}
Upvotes: 3