Я пытаюсь закодировать общий список как упражнение - я знаю, что он уже поддерживается синтаксисом, я просто пытаюсь проверить, могу ли я закодировать рекурсивную структуру данных. Как оказалось, я не могу. Я нажимаю на стену, когда хочу получить доступ к нескольким полям имеющейся ценности структуры.Как связать несколько структурных полей, не получив ошибку «use move value»?
Что я делаю, в основном это - я определить структуру, которая будет содержать список:
struct ListNode<T> {
val: T,
tail: List<T>
}
struct List<T>(Option<Box<ListNode<T>>>);
Пустой список только представленного List(None)
.
Теперь я хочу, чтобы иметь возможность добавить к списку:
impl<T> List<T> {
fn append(self, val: T) -> List<T> {
match self {
List(None) => List(Some(Box::new(ListNode { val: val, tail: List(None) }))),
List(Some(node)) => List(Some(Box::new(ListNode { val: node.val, tail: node.tail.append(val) })))
}
}
}
Ok, так что не может с ошибкой «используется перемещаемым значение: узел» в node.tail с объяснением, что это было перемещен в «node.val». Это понятно.
Итак, я смотрю на способы использования более одного поля из структуры, и я нахожу это: Avoiding partially moved values error when consuming a struct with multiple fields
Великий, так что я буду делать, что:
List(Some(node)) => {
let ListNode { val: nval, tail: ntail } = *node;
List(Some(Box::new(ListNode { val: nval, tail: ntail.append(val) })))
}
Ну, Нету, неподвижный узел перемещается при назначении («ошибка: использование перемещенного значения« узел »в« хвосте: ntail »). По-видимому, это больше не работает, как в ссылке.
Я также попытался с помощью рефов:
List(Some(node)) => {
let ListNode { val: ref nval, tail: ref ntail } = *node;
List(Some(Box::new(ListNode { val: *nval, tail: (*ntail).append(val) })))
}
На этот раз деконструкция проходит, а создание нового узла терпит неудачу с «ошибкой: не может выйти из заимствованного контента».
Я пропустил что-то очевидное здесь? Если нет, то каков правильный способ доступа к нескольким полям структуры, которые не передаются по ссылке?
Заранее благодарим за любую помощь!
EDIT: О, я, наверное, должен добавить, что я использую стабилизатор Rust 1.1.
Спасибо! Это действительно работает :) Почему Box работает именно так? Есть ли разумное объяснение? – ebvalaim
Я уверен, что это связано с тем, что unboxing deref - это некоторая магия компилятора. –
вот соответствующая ошибка: https://github.com/rust-lang/rust/issues/16223 –