1.9 В деле
Полка есть. Задачи на ней стоят ровно. Но каждый раз, когда нужно добавить или просмотреть - мастер тянется к полке напрямую, руками, без инструмента. Пока всё помещается в один взгляд - терпимо. Это и называется “пока”.
Попытка
main сейчас сама кладёт задачи в список - напрямую, через push. Пока задач три и
их добавление - единственная операция, push не мозолит глаза. Пора дать этому имя:
функция add принимает список и задачу, кладёт задачу в список. Список отдавать не нужно -
достаточно ссылки:
fn add(tasks: &Vec<Task>, task: Task) {
tasks.push(task);
}
Компилятор подсказывает:
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
Что знает компилятор
&Vec<Task> - ссылка на чтение. Через неё нельзя изменить то, на что она указывает.
push добавляет элемент - это изменение. Компилятор это видит.
В главе 1.5 та же ситуация решалась добавлением mut: task_complete принимала
&mut Task, а не &Task. Здесь принцип тот же - получатель другой:
fn add(tasks: &mut Vec<Task>, task: Task) {
tasks.push(task);
}
&mut Vec<Task> - изменяемая ссылка: функция меняет список, не захватывая его.
Заклинание
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 проходит. У add есть имя - список больше не заполняется руками.
Полный код
tqдля этой главы -1-a-task/09-the-list-at-work/.