How to fix String field does not implement `Copy`? [duplicate]
Asked Answered
O

1

34

I am building a simple command-line todo app in Rust. If I don't implement the copy trait I get this error: "move occurs because 'todo' has type 'todo::Todo', which does not implement the 'Copy' trait". When I try to implement the Copy trait for my Todo struct, I receive the following error: "field text: String does not implement the Copy trait". How do I fix this error? My code is below:

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
    }
}

Ogham answered 12/1, 2021 at 2:57 Comment(5)
In summary, you cant (and shouldn't want to) implement Copy for your struct - it means bitwise copy. You should instead derive Clone, by adding #[derive(Clone)] which will make your struct provides the clone() function.Nadeau
I implemented clone but then I get other errors: cannot borrow as mutable, value used here after move, cannot borrow as mutable.Ogham
That means you may have to rethink your code design. For example, why do you need add_todo to return Todo, and why do you need every single method on Todos consume self?Sandi
I guess I don't need to return a Todo. Do you have any idea on how to solve this error: cannot borrow self.todos` as mutable, as self is not declared as mutable`?Ogham
I fixed it by replacing self with mut selfOgham
I
23

Here you need the Clone trait instead of Copy trait. The Copy trait indicates that the variable can be copied bit-for-bit exactly as is, and that the variables of such type do not underly to move semantics.

Some limitations apply to implementations of Copy trait. Structs can implement the Copy trait only if none of their components implement the Drop trait. Since String implements the Drop trait, your struct can not implement the Copy trait.

If you are looking to make copies of your struct then you need the Clone trait.

Isiah answered 12/1, 2021 at 7:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.