Hello,
first of all, a clarification is needed: the title of this question might be totally incorrect/misleading; it's just my assumption.
I am a Rust beginner, and while reading "The Book," I came across the following example (Chapter 15, Listing 15-26):
use crate::List::{Cons, Nil };
use std::cell::RefCell;
use std::rc::Rc;
#[derive(Debug)]
enum List {
Cons(i32, RefCell<Rc<List>>),
Nil,
}
impl List {
fn tail(&self) -> Option<&RefCell<Rc<List>>> { // !!!!
match self {
Cons(a, item :&RefCell<Rc<List>>) => Some(item), // !!!!
Nil => None,
}
}
}
fn main() {
let a = Rc::new(Cons(5, RefCell::new(Rc::new(Nil))));
println!("a initial rc count = {}", Rc::strong_count(&a));
println!("a next item = {:?}", a.tail());
let b = Rc::new(Cons(10, RefCell::new(Rc::clone(&a))));
println!("a rc count after b creation = {}", Rc::strong_count(&a));
println!("b initial rc count = {}", Rc::strong_count(&b));
println!("b next item = {:?}", b.tail());
if let Some(link :&RefCell<Rc<List>>) = a.tail() { // !!!!
*link.borrow_mut() = Rc::clone(&b);
}
println!("b rc count after changing a = {}", Rc::strong_count(&b));
println!("a rc count after changing a = {}", Rc::strong_count(&a));
// Uncomment the next line to see that we have a cycle;
// it will overflow the stack
// println!("a next item = {:?}", a.tail());
}
I marked some lines with "// !!!! " because those are the ones that confuse me, and for the convenience of discussion, I added explicit type annotations provided by the development environment.
I believe I understand the intention of the example, but what doesn't fully make sense to me are the types I highlighted:
I would expect them to be "RefCell<Rc>" and not "&RefCell<Rc>," and of course, the issue lies in my incomplete understanding (the code works correctly, and I assume the automatically provided annotations are correct).
Can someone explain what is happening and where I am mistaken?
Thank you.