How to implement a remove function in a linked list in safe rust? (cannot assign to *node because is borrowed)

huangapple go评论118阅读模式
英文:

How to implement a remove function in a linked list in safe rust? (cannot assign to *node because is borrowed)

问题

  1. 结构体 Node<T> {
  2. 内容: T,
  3. 下一个: Option<Box<Node<T>>>
  4. }
  5. 结构体 LinkedList<T> {
  6. 第一个: Option<Box<Node<T>>>,
  7. 大小: i64
  8. }
  9. 实现<T: std::default::Default + std::cmp::PartialEq> LinkedList<T> {
  10. 函数 新建() -> Self {
  11. LinkedList { 第一个: None, 大小: 0 }
  12. }
  13. 函数 压栈(&mut self, 值: T) {
  14. let mut 临时节点 = Box::new(Node { 内容: 值, 下一个: None });
  15. let 旧第一个节点 = std::mem::replace(&mut self.第一个, None);
  16. 临时节点.下一个 = 旧第一个节点;
  17. self.第一个 = Some(临时节点);
  18. self.大小 += 1;
  19. }
  20. 函数 弹栈(&mut self) -> Option<T> {
  21. let mut 旧第一个 = std::mem::replace(&mut self.第一个, None);
  22. match &mut 旧第一个 {
  23. None => {
  24. return None;
  25. },
  26. Some(ptr) => {
  27. self.第一个 = std::mem::take(&mut ptr.下一个);
  28. let 返回值 = std::mem::take(&mut ptr.内容);
  29. return Some(返回值);
  30. }
  31. }
  32. }
  33. 函数 删除(&mut self, 值: T) {
  34. let mut 当前节点 = &mut self.第一个;
  35. while let Some(节点) = 当前节点 {
  36. if 节点.内容 == {
  37. *当前节点 = 节点.下一个.take();
  38. break;
  39. }
  40. 当前节点 = &mut 节点.下一个;
  41. }
  42. }
  43. }
  44. 函数 主函数() {
  45. }
英文:
  1. struct Node<T> {
  2. content: T,
  3. next: Option<Box<Node<T>>>
  4. }
  5. struct LinkedList<T> {
  6. first: Option<Box<Node<T>>>,
  7. size: i64
  8. }
  9. impl<T: std::default::Default + std::cmp::PartialEq> LinkedList<T> {
  10. fn new() -> Self {
  11. LinkedList { first: None, size: 0 }
  12. }
  13. fn push(&mut self, value: T) {
  14. let mut tmp_node = Box::new(Node { content: value, next: None });
  15. let old_first_node = std::mem::replace(&mut self.first, None);
  16. tmp_node.next = old_first_node;
  17. self.first = Some(tmp_node);
  18. self.size += 1;
  19. }
  20. fn pop(&mut self) -> Option<T> {
  21. let mut old_first = std::mem::replace(&mut self.first, None);
  22. match &mut old_first {
  23. None => {
  24. return None;
  25. },
  26. Some(ptr) => {
  27. self.first = std::mem::take(&mut ptr.next);
  28. let val_to_return = std::mem::take(&mut ptr.content);
  29. return Some(val_to_return);
  30. }
  31. }
  32. }
  33. fn remove(&mut self, value: T) {
  34. let mut current_node = &mut self.first;
  35. while let Some(node) = current_node {
  36. if node.content == value {
  37. *current_node = node.next.take();
  38. break;
  39. }
  40. current_node = &mut node.next;
  41. }
  42. }
  43. }
  44. fn main() {
  45. }

I tried to implement this function a lot but every solution I thought of, the compiler complains about some "borrow" error, in this case, the error is "cannot assign to *current_node because is borrowed". How can i avoid this error and make the current node be the next node of the linked list?

答案1

得分: 2

Actually, your code is correct, it's a limitation of the compiler that it doesn't accept it. It is accepted with the nightly Polonius borrow checker.

The simplest solution is to replace while let with is_some() and unwrap()s:

  1. fn remove(&mut self, value: T) {
  2. let mut current_node = &mut self.first;
  3. while current_node.is_some() {
  4. if current_node.as_mut().unwrap().content == value {
  5. *current_node = current_node.as_mut().unwrap().next.take();
  6. break;
  7. }
  8. current_node = &mut current_node.as_mut().unwrap().next;
  9. }
  10. }
英文:

Actually, your code is correct, it's a limitation of the compiler that it doesn't accept it. It is accepted with the nightly Polonius borrow checker.

The simplest solution is to replace while let with is_some() and unwrap()s:

  1. fn remove(&mut self, value: T) {
  2. let mut current_node = &mut self.first;
  3. while current_node.is_some() {
  4. if current_node.as_mut().unwrap().content == value {
  5. *current_node = current_node.as_mut().unwrap().next.take();
  6. break;
  7. }
  8. current_node = &mut current_node.as_mut().unwrap().next;
  9. }
  10. }

huangapple
  • 本文由 发表于 2023年5月21日 01:46:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76296596.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定