← Table of contents

1.9 The List at Work

The shelf exists. Tasks sit on it in order. But every time something needs to be added or reviewed, the craftsman reaches for the shelf directly - by hand, without a tool. While everything fits in a single glance, this is tolerable. That is what “for now” means.

The Attempt

main currently puts tasks into the list directly, through push. While there are three tasks and adding them is the only operation, push does not stand out. Time to give this a name: an add function that takes a list and a task and puts the task in. The list does not need to be handed over - a reference is enough:

fn add(tasks: &Vec<Task>, task: Task) {
    tasks.push(task);
}

The compiler responds:

error[E0596]: cannot borrow `*tasks` as mutable, as it is behind a `&` reference
 --> src/main.rs:XX:XX
  |
XX |     tasks.push(task);
  |     ^^^^^ `tasks` is a `&` reference, so the data it refers to cannot be borrowed as mutable

What the Compiler Knows

&Vec<Task> is a read-only reference. It cannot be used to modify what it points to. push adds an element - that is a modification. The compiler sees it.

In chapter 1.5 the same situation was resolved by adding mut: task_complete took &mut Task instead of &Task. The principle is the same here - only the recipient differs:

fn add(tasks: &mut Vec<Task>, task: Task) {
    tasks.push(task);
}

&mut Vec<Task> is a mutable reference: the function modifies the list without taking ownership of it.

The Enchantment

fn main() {
    let mut tasks: Vec<Task> = Vec::new();

    add(&mut tasks, Task::new(1, "Buy coffee"));
    add(&mut tasks, Task::new(2, "Buy milk"));
    add(&mut tasks, Task::new(3, "Buy eggs"));

    let task = &mut tasks[0];
    task.complete();

    if task.is_done() {
        println!("Task 1 done");
    }

    for task in &tasks {
        println!("#{}: {} - {:?}", task.id, task.title, task.status);
    }
}
Task 1 done
#1: Buy coffee - Done
#2: Buy milk - Todo
#3: Buy eggs - Todo

make ci passes. add has a name - the list is no longer filled by hand.

The complete tq code for this chapter is in 1-a-task/09-the-list-at-work/.