How can a function append a value to a vector and also return that value?

How do I work around

You don’t “work around” this type of problem. Ownership is a fundamental concept in Rust and you have to understand it.

Solutions

Make your Card implicitly copyable via Copy

#[derive(Debug, Copy, Clone)]
enum Card { /* ... */ }

Make your Card explicitly copyable via Clone

#[derive(Debug, Clone)]
enum Card { /* ... */ }

fn rotate_card(deck: &mut Deck) -> Card {
    let top_card = deck.remove(0);
    deck.push(top_card.clone());
    top_card
}

Return a reference to the card

You can return a reference to the last card instead of the card as a value:

fn rotate_card(deck: &mut Deck) -> &mut Card {
    let top_card = deck.remove(0);
    deck.push(top_card);
    deck.last_mut().unwrap()
}

Use reference-counting

A type like Rc or Arc can allow shared ownership of a value:

use std::rc::Rc;

type Deck = Vec<Rc<Card>>;

fn rotate_card(deck: &mut Deck) -> Rc<Card> {
    let top_card = deck.remove(0);
    deck.push(top_card.clone());
    top_card
}

Other notes

This is a useless function signature:

fn rotate_card(deck: &mut Deck) -> (Card, &mut Deck) 

There’s no reason to return the Deck back to the caller; they already have that reference. Remove that.

Slices (and Vecs via DerefMut) have the rotate_left method; you don’t need to reimplement it.

Leave a Comment