我正在遵循本书中的链表实现。和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>,
}
Run Code Online (Sandbox Code Playgroud)
我有一个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();
}
}
Run Code Online (Sandbox Code Playgroud)
该代码编译良好。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);
}
Run Code Online (Sandbox Code Playgroud)
如果我注释掉该println!行,则测试通过。所以基本上调试打印list导致了这里的堆栈溢出。我无法理解到底为什么。
完整代码的Playground 链接。
我已经对代码进行了实验,以明确下面的行是否导致了问题。
println!("{:?}", list);
Run Code Online (Sandbox Code Playgroud)
所以我的猜测是,既然list有一个类型std::rc::Rc并且println!宏需要该值的引用,那么它会以某种方式在某处创建一个循环。但我无法具体确定问题所在。
派生impl Debug for Node打印 和prev,next但prev将尝试打印其下一个节点(即当前节点)并将next尝试打印其prev(同上),因此这是无限递归。
您需要Debug手动实现:
impl<T: Debug> std::fmt::Debug for Node<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Node")
.field("elem", &self.elem)
.field("next", &self.next)
.finish()
}
}
Run Code Online (Sandbox Code Playgroud)
如果您不想打印,也可以手动 impl Debugfor 。Listtail
| 归档时间: |
|
| 查看次数: |
249 次 |
| 最近记录: |