如何解决“String字段未实现`Copy`”的问题?

28

我正在使用Rust构建一个简单的命令行待办事项应用程序。如果我不实现复制特性,则会出现以下错误:"move occurs because 'todo' has type 'todo::Todo', which does not implement the 'Copy' trait"。当我尝试为我的Todo结构实现Copy特性时,我收到以下错误消息:"field text: String does not implement the Copy trait"。如何修复此错误?以下是我的代码:

pub type todo_type = Vec<Todo>;

#[derive(Copy)]
pub struct Todo {
    id: usize,
    text: String,
    completed: bool,
}

impl Todo {
    pub fn new(text: String, id: usize) -> Todo {
        Todo {
            text,
            id,
            completed: false,
        }
    }
}

pub struct Todos {
    todos: todo_type,
}

impl Todos {
    pub fn new(todos: todo_type) -> Todos {
        Todos { todos }
    }

    pub fn get_all_todos(self) -> todo_type {
        self.todos
    }

    pub fn get_single_todo(self, todo_index: usize) -> Todo {
        unimplemented!()
    }

    pub fn add_todo(self, text: String) -> Todo {
        let id: usize = 1;

        if self.todos.len() == 0 {
            let id = 1;
        } else {
            let last_todo = match self.todos.len() {
                0 => None,
                n => Some(&self.todos[n - 1]),
            };
            let id = last_todo.unwrap().id;
        }

        let todo = Todo::new(text, id);
        self.todos.push(todo);

        todo
    }

    pub fn remove_todo(self, todo_index: usize) -> bool {
        self.todos.remove(todo_index);

        true
    }
}


总之,你不能(也不应该)为你的结构体实现Copy - 这意味着位拷贝。相反,你应该通过添加#[derive(Clone)]来派生Clone,这将使你的结构体提供clone()函数。 - Michael Anderson
1
我实现了克隆,但是接着出现了其他错误:无法作为可变借用,值在移动后被使用,无法作为可变借用。 - Henry Boisdequin
1
这意味着您可能需要重新思考您的代码设计。例如,为什么您需要add_todo返回Todo,以及为什么您需要在Todos上的每个单独方法都消耗self - Cerberus
我猜我不需要返回一个 Todo。你有什么想法来解决这个错误:“无法将 self.todos 借为可变的,因为 self 没有声明为可变的”? - Henry Boisdequin
我通过将 self 替换为 mut self 来修复它。 - Henry Boisdequin
1个回答

17

在这里,你需要使用Clone特质而不是Copy特质。Copy特质表示变量可以按位精确地复制,并且此类类型的变量不具有移动语义。

实现Copy特质的限制会适用于某些情况。如果结构体的任何成员实现了Drop特质,则结构体只能实现Clone特质,而不能实现Copy特质。由于String实现了Drop特质,所以你的结构体不能实现Copy特质。

如果你想要复制你的结构体,则需要使用Clone特质。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接