Как мне обработать / обойти "Невозможно назначить ... который находится за & ссылкой" в Rust? - PullRequest
0 голосов
/ 14 января 2020

Я бы реализовал простой связанный список. Это (рабочий) код, который у меня был до сих пор:

pub struct LinkedList<T> {
    start: Option<Box<Link<T>>>,
}

impl<T> LinkedList<T> {
    pub fn new() -> LinkedList<T> {
        return LinkedList { start: None };
    }
}

struct Link<T> {
    value: Box<T>,
    next: Option<Box<Link<T>>>,
}

impl<T> Link<T> {
    fn new_end(value: T) -> Link<T> {
        return Link::new(value, None);
    }

    fn new(value: T, next: Option<Box<Link<T>>>) -> Link<T> {
        return Link {
            value: Box::new(value),
            next,
        };
    }
}

Следующим в списке является метод добавления в список; вот что я придумал:

pub fn append(&mut self, element: T) {
    // Create the link to append
    let new_link = Some(Box::new(Link::new_end(element)));

    // Find the last element of the list. None, if the list is empty
    let mut last = &self.start;
    while let Some(link) = last {
        last = &link.next;
    }

    // Insert the new link at the correct position
    match last {
        None => self.start = new_link,
        Some(last) => last.next = new_link, // This fails
    }
}

Точная ошибка компилятора:

error[E0594]: cannot assign to `last.next` which is behind a `&` reference

Я смутно понимаю проблему; Вы не можете изменить неизменную ссылку. Но, делая ссылки изменяемыми, кажется, делает ошибки еще хуже.

Как можно справиться с такого рода ошибками? Есть ли простое быстрое исправление, или вы полностью изменили свой код в Rust?

1 Ответ

3 голосов
/ 14 января 2020

Ваш код почти сработал. Если вы связываете изменчиво :

impl<T> LinkedList<T> {
    pub fn append(&mut self, element: T) {
        // Create the link to append
        let new_link = Some(Box::new(Link::new_end(element)));

        // Find the last element of the list. None, if the list is empty
        let mut last = &mut self.start;
        while let Some(link) = last {
            last = &mut link.next;
        }

        // Insert the new link at the correct position
        match last {
            None => self.start = new_link,
            Some(ref mut last) => last.next = new_link,
        }
    }
}

К вашему сведению, , то ответ на этот недавний вопрос очень хорош в разъяснении вопроса об изменчивости, типе и привязке в Ржавчина.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...