我正在按照这本书中的链表实现进行操作。
List
和 Node
结构如下 -
type Link<T> = Option<Rc<RefCell<Node<T>>>>;
#[derive(Debug)]
pub struct List<T> {
head: Link<T>,
tail: Link<T>,
}
#[derive(Debug)]
struct Node<T> {
elem: T,
next: Link<T>,
prev: Link<T>,
}
我有一个类似下面的
push_front
方法 - pub fn push_front(&mut self, elem: T) {
let new_node = Node::new(elem);
let new_node = Rc::new(RefCell::new(new_node));
let mut old_head = self.head.take();
old_head.as_mut().map(|node| {
node.borrow_mut().prev = Some(Rc::clone(&new_node));
});
new_node.borrow_mut().next = old_head.clone();
self.head = Some(new_node);
if self.tail.is_none() {
self.tail = self.head.clone();
}
}
代码可以正常编译。但是,每当我在测试中加入一个调试打印代码
List
,就会出现一个测试失败,并显示消息 thread 'tests::test_list_1' has overflowed its stack
。 #[test]
fn test_list_1() {
let mut list = List::new();
list.push_front(1);
list.push_front(2);
list.push_front(3);
println!("{:?}", list);
// assert!(false);
}
如果我将
println!
这行注释掉,那么测试就能通过。所以基本上是list
的调试输出导致了栈溢出问题。我无法理解究竟是什么原因导致了这个问题。完整代码的Playground链接。
我已经对代码进行了一些实验,找到了导致问题的具体代码行。
println!("{:?}", list);
因为list
具有类型std::rc::Rc
,而println!
宏获取值的引用,所以我猜想它在某个地方创建了一个循环。虽然我无法具体识别问题。