在Rust中将节点附加到空的LinkedList,self.head.borrow_next()为None,而不是self.tail

cld4siwp  于 2022-12-29  发布在  其他
关注(0)|答案(1)|浏览(142)

我曾试图重新实现LinkedIn的 rust ,下面是我的代码:

  1. #![allow(dead_code)]
  2. use std::cell::{RefCell, Ref, RefMut};
  3. use std::rc::Rc;
  4. type WrappedNode<T> = Rc<RefCell<Node<T>>>;
  5. #[derive(Debug, PartialOrd, PartialEq, Clone)]
  6. pub struct Node<T> where
  7. T: Clone
  8. {
  9. next: Option<WrappedNode<T>>,
  10. data: T,
  11. }
  12. #[derive(Debug, PartialOrd, PartialEq)]
  13. pub struct LinkedList<T> where
  14. T: Clone
  15. {
  16. head: Option<WrappedNode<T>>,
  17. tail: Option<WrappedNode<T>>,
  18. }
  19. impl<T> Iterator for LinkedList<T> where
  20. T: Clone
  21. {
  22. type Item = WrappedNode<T>;
  23. fn next(&mut self) -> Option<Self::Item> {
  24. unimplemented!()
  25. }
  26. }
  27. impl<T> Node<T> where
  28. T: Clone
  29. {
  30. pub fn new(data: T) -> Self {
  31. Self {
  32. next: None,
  33. data,
  34. }
  35. }
  36. pub fn borrow_data(self: &Self) -> &T {
  37. &self.data
  38. }
  39. pub fn borrow_next(self: &Self) -> Option<Ref<Node<T>>> {
  40. match &self.next {
  41. Some(next_exists) => {
  42. Some(next_exists.borrow())
  43. },
  44. None => {
  45. None
  46. }
  47. }
  48. }
  49. pub fn borrow_mut_next(self: &Self) -> Option<RefMut<Node<T>>> {
  50. match &self.next {
  51. Some(next_exists) => {
  52. Some(next_exists.borrow_mut())
  53. },
  54. None => {
  55. None
  56. }
  57. }
  58. }
  59. pub fn set_next(self: &mut Self, next: Node<T>) {
  60. let next_node = Rc::new(RefCell::new(next));
  61. self.next = Some(next_node);
  62. }
  63. }
  64. impl<T> LinkedList<T> where
  65. T: Clone
  66. {
  67. pub fn new_empty() -> Self {
  68. Self {
  69. head: None,
  70. tail: None,
  71. }
  72. }
  73. pub fn new_with_node(first_node: Node<T>) -> Self {
  74. let mut new_ll = Self::new_empty();
  75. Self::append(&mut new_ll, first_node);
  76. new_ll
  77. }
  78. pub fn append(&mut self, node: Node<T>) {
  79. assert!(node.next.is_none()); // make sure its not joining two linkedlists
  80. match self.tail.take() {
  81. Some(old_tail) => {
  82. old_tail
  83. .borrow_mut()
  84. .set_next(node.clone());
  85. },
  86. None => {
  87. let mut node_clone = node.clone();
  88. node_clone.next = self.tail.clone();
  89. self.head = Some(Rc::new(RefCell::new(node_clone)));
  90. }
  91. }
  92. self.tail = Some(Rc::new(RefCell::new(node)));
  93. }
  94. }
  95. // CRUD -> create new, add to head tail, read head tail, update anywhere, delete anywhere, delete head tail
  96. #[cfg(test)]
  97. mod tests {
  98. use super:: {Node, LinkedList};
  99. use std::rc::Rc;
  100. use std::cell::RefCell;
  101. #[test]
  102. fn test_node_ref_data() {
  103. let node = Node::new(5);
  104. assert_eq!(node.borrow_data(), &5);
  105. }
  106. #[test]
  107. fn test_node_ref_next() {
  108. let node = Node::new(5);
  109. assert!(node.borrow_next().is_none());
  110. }
  111. #[test]
  112. fn test_node_set_next() {
  113. let mut node = Node::new(33);
  114. let next_node = Node::new(34);
  115. Node::set_next(&mut node,
  116. next_node);
  117. assert_eq!(node
  118. .borrow_next()
  119. .unwrap()
  120. .borrow_data(), &34);
  121. }
  122. #[test]
  123. fn test_ll_new_empty() {
  124. #[derive(Debug, PartialEq, PartialOrd, Clone)]
  125. struct NTH;
  126. let new_ll = LinkedList::<NTH>::new_empty();
  127. assert_eq!(new_ll, LinkedList{head: None, tail: None})
  128. }
  129. #[test]
  130. fn test_ll_new_with_node() {
  131. let new_node = Node::new(45);
  132. let new_node_two = new_node.clone();
  133. let new_node_three = new_node.clone();
  134. let new_ll = LinkedList::new_with_node(new_node);
  135. let new_node_two = Some(Rc::new(RefCell::new(new_node_two)));
  136. let new_node_three = Some(Rc::new(RefCell::new(new_node_three)));
  137. assert_eq!(new_ll, LinkedList{head: new_node_two, tail: new_node_three})
  138. }
  139. #[test]
  140. fn test_ll_new_with_node_head_borrow_next_is_tail() {
  141. let new_node = Node::new(45);
  142. let new_node_two = new_node.clone();
  143. let new_ll = LinkedList::new_with_node(new_node);
  144. let new_node_two = Some(Rc::new(RefCell::new(new_node_two)));
  145. assert_eq!(new_ll
  146. .head
  147. .unwrap()
  148. .borrow()
  149. .borrow_next()
  150. .unwrap()
  151. .borrow_data(), new_node_two.unwrap().borrow().borrow_data());
  152. }
  153. #[test]
  154. fn test_ll_append_tail() {
  155. let new_node = Node::new(45);
  156. let new_node_two = new_node.clone();
  157. let mut new_ll = LinkedList::new_with_node(new_node);
  158. let new_node_two = Some(Rc::new(RefCell::new(new_node_two)));
  159. let append_node = Node::new(77);
  160. LinkedList::append(&mut new_ll, append_node);
  161. assert_eq!(new_ll
  162. .tail
  163. .unwrap()
  164. .borrow()
  165. .borrow_data(), &77)
  166. }
  167. #[test]
  168. fn test_ll_append_first_borrow_next() {
  169. let new_node = Node::new(45);
  170. let new_node_two = new_node.clone();
  171. let mut new_ll = LinkedList::new_with_node(new_node);
  172. let new_node_two = Some(Rc::new(RefCell::new(new_node_two)));
  173. let append_node = Node::new(77);
  174. LinkedList::append(&mut new_ll, append_node);
  175. assert_eq!(new_ll
  176. .head
  177. .unwrap()
  178. .borrow()
  179. .borrow_next()
  180. .unwrap()
  181. .borrow_data(), &77)
  182. }
  183. // end of tests
  184. }

两个测试失败,如下所示:

  1. running 8 tests
  2. test same_type_linked_list::tests::test_ll_new_empty ... ok
  3. test same_type_linked_list::tests::test_ll_append_tail ... ok
  4. test same_type_linked_list::tests::test_ll_new_with_node_head_borrow_next_is_tail ... FAILED
  5. test same_type_linked_list::tests::test_ll_append_first_borrow_next ... FAILED
  6. test same_type_linked_list::tests::test_ll_new_with_node ... ok
  7. test same_type_linked_list::tests::test_node_ref_data ... ok
  8. test same_type_linked_list::tests::test_node_set_next ... ok
  9. test same_type_linked_list::tests::test_node_ref_next ... ok
  10. failures:
  11. ---- same_type_linked_list::tests::test_ll_new_with_node_head_borrow_next_is_tail stdout ----
  12. thread 'same_type_linked_list::tests::test_ll_new_with_node_head_borrow_next_is_tail' panicked at 'called `Option::unwrap()` on a `None` value', src/same_type_linked_list.rs:176:14
  13. ---- same_type_linked_list::tests::test_ll_append_first_borrow_next stdout ----
  14. thread 'same_type_linked_list::tests::test_ll_append_first_borrow_next' panicked at 'called `Option::unwrap()` on a `None` value', src/same_type_linked_list.rs:210:16
  15. note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
  16. failures:
  17. same_type_linked_list::tests::test_ll_append_first_borrow_next
  18. same_type_linked_list::tests::test_ll_new_with_node_head_borrow_next_is_tail

我怀疑在向空的LinkedList追加新的Node<T>(具体为Node<u64>)时,self.head.next没有指向self.tail,尽管我明确地设置了它。当我对borrow_next()返回的None值调用unwrap()时,错误发生。Node<T>的关联方法返回字段.next的引用。这意味着理想情况下应该返回对new_ll.tail的引用的new_ll.head.borrow_next()改为返回None,这意味着当第一节点被附加/插入到完全空的LinkedList中时,它不指向new_11.tail。

xnifntxz

xnifntxz1#

查看您的代码,head节点是您在中给予的节点

  1. LinkedList::new_with_node()

它的召唤

  1. pub fn new_empty() -> Self {
  2. Self {
  3. head: None,
  4. tail: None,
  5. }

也就是说,它初始化时没有头节点,所以当你用一个节点构造你的列表时,你就添加了一个头

  1. pub fn new_with_node(first_node: Node<T>) -> Self {
  2. let mut new_ll = Self::new_empty();
  3. Self::append(&mut new_ll, first_node);
  4. new_ll
  5. }
  6. pub fn append(&mut self, node: Node<T>) {
  7. assert!(node.next.is_none()); // make sure its not joining two linkedlists
  8. match self.tail.take() {
  9. Some(old_tail) => {
  10. old_tail
  11. .borrow_mut()
  12. .set_next(node.clone());
  13. },
  14. None => {
  15. let mut node_clone = node.clone();
  16. node_clone.next = self.tail.clone();
  17. self.head = Some(Rc::new(RefCell::new(node_clone)));
  18. }
  19. }

还可以通过显式地将新创建的列表作为self传递来调用append。

  1. Self::append(&mut new_ll, first_node);

你可以称之为

  1. new_ll.append(first_node)

您假设在测试中头部之外还有另一个节点:

  1. assert_eq!(new_ll
  2. .head
  3. .unwrap()
  4. .borrow()
  5. .borrow_next()
  6. .unwrap()
  7. .borrow_data(), &77)
展开查看全部

相关问题