Связанный список Rust не может заимствовать предыдущий и следующий элементы как изменяемые (просто нужна неизменная ссылка) - PullRequest
0 голосов
/ 25 апреля 2020

В настоящее время я работаю над небольшим приложением для имитации (многоцепных) маятников. Чтобы сохранить их, я решил go для std :: collection :: LinkedList.

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

Мне действительно не нужна изменяемая ссылка на них, но API связанного списка не позволяет мне взять неизменяемый. Но я полагаю, что это все равно не изменит мнение компилятора, поскольку он все еще изменчив и заимствует некоторые неизменные.

Мой код выглядит следующим образом:

let mut cursor = /* some linked list with 0 or more elements */.cursor_front_mut();

// the first element gets a phantom parent, that has no effect on the calculation
let mut first = Pendulum::zero_center();
// same with the last element. But we don't know the position of this phantom yet.
let mut last;

while let Some(current) = cursor.current() { // << first mutable borrow occurs here
    { 
        // new scope, so I don't mutate the cursor while holding mutable references
        // to the surrounding elements
        // (I don't really need the next two borrows to be mutable)

        let parent = match cursor.peek_prev() { // << second mutable borrow occurs here
            Some(parent) => parent,
            None => &mut first
        };
        let child = match cursor.peek_next() { // third mutable borrow occurs here
            Some(child) => child,
            None => {
                last = Pendulum::zero(current.bottom_pos); // << bottom_pos is of type Copy
                &mut last
            }
        };

        // update the current pendulum
        // update does take a immutable reference of parent and child
        // since it only needs to read some values of them
        current.update(parent, child);
    }
    cursor.move_next();
}

Если я оберну этот код небезопасным { }, компилятору все равно, и он говорит мне, что у меня есть несколько изменяемых заимствований + ненужный unsafe блок.

Было бы здорово, если бы кто-то мог мне помочь!
Если использование LinkedList Всего руби sh здесь и есть лучший способ сделать это, пожалуйста, дайте мне знать!

Большое спасибо заранее!

1 Ответ

0 голосов
/ 29 апреля 2020

Как правило, изменяемые ссылки требуют эксклюзивного доступа к тому, на что они указывают, и небезопасные блоки не влияют на это. Необработанные указатели не имеют этого требования, поэтому при написании кода, который нарушает эти требования, придется использовать необработанные указатели.

Реализация связанного списка с небезопасным Rust выходит за рамки ответа SO, но я рекомендую Learning Rust со слишком большим количеством связанных списков в качестве ресурса о способах решения этой проблемы.

Иногда построение связанного списка с использованием индексов в векторе является хорошим альтернативным подходом, побочным действием которого являются любые проблемы во многих Требования, предъявляемые Rust к своим ссылкам.

...