首页 > 解决方案 > 无法移出递归结构的共享引用

问题描述

我正在尝试在 Rust 中实现 Gale-Shapley 算法,我需要声明一个这样的递归结构:

#[derive(Eq, PartialEq, PartialOrd)]
struct Person {
    name: char,
    preference: Vec<Person>,
    pref_index: usize,
    candidates: Vec<Person>,
    partner: Option<Box<Person>>, // using Box makes it easier to declare recursive structs
}

impl Person {
    fn propose_to_next(&mut self) {
        /* propose to next most preferred person */

        if self.pref_index >= self.preference.len() {
            ()
        }

        let person = self.preference[self.pref_index];
        self.candidates.push(person);

        self.pref_index += 1;
    }

    fn pick_preferred(&mut self) {
        /* pick the next more preferred partner or stay with the current one */

        for person in &self.preference {
            let p = Some(Box::new(*person));

            if p == self.partner {
                break;
            } else if self.candidates.contains(&person) {
                self.partner = p;
                break;
            }
        }
    }
}

但这给了我错误

error[E0507]: cannot move out of index of `std::vec::Vec<Person>`
  --> src/lib.rs:18:22
   |
18 |         let person = self.preference[self.pref_index];
   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |                      |
   |                      move occurs because value has type `Person`, which does not implement the `Copy` trait
   |                      help: consider borrowing here: `&self.preference[self.pref_index]`

error[E0507]: cannot move out of `*person` which is behind a shared reference
  --> src/lib.rs:29:35
   |
29 |             let p = Some(Box::new(*person));
   |                                   ^^^^^^^ move occurs because `*person` has type `Person`, which does not implement the `Copy` trait

我该如何解决?我的方法有缺陷吗?我尝试了一种仅使用向量和哈希图的非 OO 方法,但它很难看,因为我必须在每个函数中传递所有内容。

标签: rust

解决方案


在您的情况下,这可能应该这样做。请注意,该结构如何不拥有preference向量元素或伙伴元素的所有权,而只是拥有对它们的(简单来说是静态的)引用。

另请注意,您必须实现该PartialEq特征才能使其正常工作

use std::vec::Vec;

struct Person {
    name: char,
    preference: Vec<&'static Person>,
    partner: Option<&'static Person>
}

impl Person {
    fn pick_preferred(&mut self, candidates: &Vec<Person>) {
        for person in &self.preference {
            if candidates.contains(&person) {
                self.partner = Some(person);
            }
        }
    }
}

impl PartialEq for Person {
    fn eq(&self, other: &Self) -> bool {
        self.name == other.name
    }
}

pub fn main() {
    let candidates: Vec<Person>;
    let p: Person;
    ....
}

游乐场链接:https ://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=4b1fab2d4f2188c8d50fd21762ad126c


推荐阅读