使用泛型和函数指针克隆结构时如何修复 "the method `clone` exists but the following trait bounds were not satisfied"?

How do I fix "the method `clone` exists but the following trait bounds were not satisfied" when cloning a struct with generics and a function pointer?

我正在编写一个将在终端中创建菜单界面的函数。要使用该函数,需要传递一个 Vec<menu_option>

#[derive(Clone)]
pub struct menu_option<'a, T> {
    pub command: &'a str,
    pub description: &'a str,
    pub action: menu_option_action<'a, T>,
}

#[derive(Clone)]
pub enum menu_option_action<'a, T> {
    sub_menu(Vec<menu_option<'a, T>>),
    callback(fn(state: T) -> T),
    leave,
}

我在设计菜单的时候,可以有多个层次,可以有一个menu_action的重复。即每一层都有一个"leave"/"return":

// In my actual code I construct a vector of `menu_option`s
fn example() {
    type StateType = i32;
    let mut state: StateType = 88;
    let leave_option: menu_option<&mut StateType> = menu_option::<&mut StateType> {
        command: "l",
        description: "leave",
        action: menu_option_action::leave,
    };

    let a = leave_option.clone();
}
error[E0599]: no method named `clone` found for struct `menu_option<'_, &mut i32>` in the current scope
   --> src/lib.rs:24:26
    |
2   | pub struct menu_option<'a, T> {
    | -----------------------------
    | |
    | method `clone` not found for this
    | doesn't satisfy `menu_option<'_, &mut i32>: std::clone::Clone`
...
24  |     let a = leave_option.clone();
    |                          ^^^^^ method not found in `menu_option<'_, &mut i32>`
    |
    = note: the method `clone` exists but the following trait bounds were not satisfied:
            `&mut i32: std::clone::Clone`
            which is required by `menu_option<'_, &mut i32>: std::clone::Clone`
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `clone`, perhaps you need to implement it:
            candidate #1: `std::clone::Clone`

我该如何解决这个问题?

我尝试在线搜索但找不到解决方案,至少没有找到适合我的解决方案(我认为我找到的是旧的 Rust)

我不知道是什么阻止了克隆,因为 T 类型的唯一用途是我认为可以克隆的函数指针。

当您在 menu_optionmenu_option_action 上自己实施 Clone 时,它会起作用。默认情况下,由于您的 struct/enum 具有类型参数,因此 #[derive(Clone)] 属性的宏扩展会将您的类型的克隆实现限制为 T: Clone.

在您的情况下,不仅不需要此要求,而且也不太可能得到尊重(例如 &mut T 未实施 Clone)。通过手动实施 Clone,您可以摆脱 T: Clone 要求并且它有效!

请注意,函数指针实现了 Copy,这就是 menu_option_action::callback(*f) 起作用的原因:

type StateType = i32;

pub struct menu_option<'a, T> {
    pub command: &'a str,
    pub description: &'a str,
    pub action: menu_option_action<'a, T>,
}

impl<'a, T> Clone for menu_option<'a, T> {
    fn clone(&self) -> Self {
        menu_option {
            command: self.command.clone(),
            description: self.description.clone(),
            action: self.action.clone(),
        }
    }
}

pub enum menu_option_action<'a, T> {
    sub_menu(Vec<menu_option<'a, T>>),
    callback(fn(T) -> T),
    leave,
}

impl<'a, T> Clone for menu_option_action<'a, T> {
    fn clone(&self) -> Self {
        match self {
            menu_option_action::sub_menu(sub) => menu_option_action::sub_menu(sub.to_vec()),
            menu_option_action::callback(f) => menu_option_action::callback(*f),
            menu_option_action::leave => menu_option_action::leave,
        }
    }
}

fn main() {
    let mut state: StateType = 88;
    let leave_option: menu_option<&mut StateType> = menu_option {
        command: "l",
        description: "leave",
        action: menu_option_action::leave,
    };

    let a = leave_option.clone();
}