一个函数如何将一个值附加到一个向量以及 return 该值?

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

我正在尝试编写一个函数 rotate_card,它接受一个向量作为输入,将向量的前面的元素旋转到后面,returns 一对包含旋转元素和向量的元素旋转的结果。

#[derive(Debug)]
enum Card {
    Ace,
    King,
    Queen,
    Jack,
}

type Deck = Vec<Card>;

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

fn main() {
    let mut my_deck: Deck = vec![Card::Ace, Card::King, Card::Queen, Card::Jack];
    let z: (Card, &mut Deck) = rotate_card(&mut my_deck);
    println!("The value of z is: {:?}.", z);
} // end main
error[E0382]: use of moved value: `top_card`
  --> src/main.rs:14:6
   |
13 |     deck.push(top_card);
   |               -------- value moved here
14 |     (top_card, deck)
   |      ^^^^^^^^ value used here after move
   |
   = note: move occurs because `top_card` has type `Card`, which does not implement the `Copy` trait

如何解决 value used after move 错误?

How do I work around

你不会"work around"这种类型的问题。所有权是 Rust 中的一个基本概念,您必须了解它。

解决方案

通过 Copy

使您的 Card 可隐式复制
#[derive(Debug, Copy, Clone)]
enum Card { /* ... */ }

通过 Clone

使您的 Card 明确可复制
#[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 对卡片的引用

您可以return引用最后一张卡片而不是卡片作为值:

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

使用引用计数

Rc or Arc 这样的类型可以允许共享一个值的所有权:

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
}

其他说明

这是一个无用的函数签名:

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

没有理由 return 将 Deck 返回给调用者;他们已经有那个参考。删除那个。

切片(和 Vec 通过 DerefMut 切片)有 rotate_left 方法;你不需要重新实现它。