After reading the section in the Rust book on Smart Pointers and Interior mutability, I tried, as a personal exercise, to write a function that would traverse a linked list of smart pointers and return the "last" element in the list:
#[derive(Debug, PartialEq)]
enum List {
Cons(Rc<RefCell<i32>>, Rc<List>),
Nil,
}
use crate::List::{Cons, Nil};
fn get_last(list: &List) -> &List {
match list {
Nil | Cons(_, Nil) => list,
Cons(_, next_list) => get_last(next_list),
}
}
This code results in the following error:
| Nil | Cons(_, Nil) => list,
| ^^^ expected struct `std::rc::Rc`, found enum `List
I was able to get it to work by using a "match guard" and explicitly dereferncing on the Cons(_, x)
pattern:
fn get_last(list: &List) -> &List {
match list {
Nil => list,
Cons(_, next_list) if **next_list == Nil => list,
Cons(_, next_list) => get_last(next_list),
}
}
Given what I've learned about implicit dereferencing and the Deref
trait implementation for Rc
, I would have expected my first attempt to work. Why must I explicitly dereference in this example?