I am trying to encode a general recursive data structure. As it turned out, I canโt, when I hit the wall, when I want to access several fields of the structureโs own value.
I define a structure that will contain a list:
struct ListNode<T> { val: T, tail: List<T> } struct List<T>(Option<Box<ListNode<T>>>);
An empty list is represented by List(None) .
I want to be able to add to the list:
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), }))), } } }
This fails with a clear error:
error[E0382]: use of moved value: 'node' --> src/main.rs:17:23 | 16 | val: node.val, | -------- value moved here 17 | tail: node.tail.append(val), | ^^^^^^^^^ value used here after move | = note: move occurs because 'node.val' has type 'T', which does not implement the 'Copy' trait
I was looking for ways to use more than one field of the structure and found the "Avoid partially moved values" error when using a structure with multiple fields , so I will do this:
List(Some(node)) => { let ListNode { val: nval, tail: ntail, } = *node; List(Some(Box::new(ListNode { val: nval, tail: ntail.append(val), }))) }
Well no, it's the same mistake. Apparently, this no longer works, as in the link.
I also tried using links:
List(Some(node)) => { let ListNode { val: ref nval, tail: ref ntail, } = *node; List(Some(Box::new(ListNode { val: *nval, tail: (*ntail).append(val), }))) }
This time the deconstruction passes, but the creation of a new node fails with:
error[E0507]: cannot move out of borrowed content --> src/main.rs:21:26 | 21 | val: *nval, | ^^^^^ cannot move out of borrowed content error[E0507]: cannot move out of borrowed content --> src/main.rs:22:27 | 22 | tail: (*ntail).append(val), | ^^^^^^^^ cannot move out of borrowed content
Am I missing something obvious here? If not, then how to access multiple fields of a structure that is not passed by reference? I am using Rust 1.1.