Card 1 / 12
Define the next field and the constructor for a heap-allocated list node. Box<T> stores a value on the heap behind a fixed-size pointer, and Option<Box<ListNode>> lets the type nest recursively, with None marking the end of the list.
| call | state afterwards |
|---|---|
ListNode::new(42) |
val == 42, next == None |
head.next = Some(Box::new(ListNode::new(2))) |
head.next.as_ref().unwrap().val == 2 |
The tests peek at nodes with as_ref(), which turns &Option<Box<ListNode>> into Option<&Box<ListNode>> so unwrap() borrows the node instead of moving it.
A struct with next: Option<Box<Self>> creates a recursive type with a clear termination.
/// A linked list node using Box for heap allocation
struct ListNode {
val: i32,
next: Option<Box<ListNode>>,
}
impl ListNode {
/// Create a new node with the given value
fn new(val: i32) -> Self {
ListNode { val, next: None }
}
}Card 2 / 12
Count the nodes in a linked list. The function borrows the list (&Option<Box<ListNode>>) rather than consuming it, and pattern matching on Option is the idiomatic way to handle the end of the list.