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

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

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

问题

结构体 Node<T> {
  内容: T,
  下一个: Option<Box<Node<T>>>
}

结构体 LinkedList<T> {
  第一个: Option<Box<Node<T>>>,
  大小: i64
}

实现<T: std::default::Default + std::cmp::PartialEq> LinkedList<T> {
  函数 新建() -> Self {
    LinkedList { 第一个: None, 大小: 0 }
  }

  函数 压栈(&mut self, 值: T) {
    let mut 临时节点 = Box::new(Node { 内容: 值, 下一个: None });
    let 旧第一个节点 = std::mem::replace(&mut self.第一个, None);
    临时节点.下一个 = 旧第一个节点;
    self.第一个 = Some(临时节点);

    self.大小 += 1;
  }

  函数 弹栈(&mut self) -> Option<T> {
    let mut 旧第一个 = std::mem::replace(&mut self.第一个, None);
    match &mut 旧第一个 {
      None => {
        return None;
      },
      Some(ptr) => {
        self.第一个 = std::mem::take(&mut ptr.下一个);
        let 返回值 = std::mem::take(&mut ptr.内容);
        return Some(返回值);
      }
    }
  }

  函数 删除(&mut self, 值: T) {
    let mut 当前节点 = &mut self.第一个;

    while let Some(节点) = 当前节点 {
      if 节点.内容 == 值 {
        *当前节点 = 节点.下一个.take();
        break;
      }
      当前节点 = &mut 节点.下一个;
    }
  }
}

函数 主函数() {
  
}
英文:
struct Node<T> {
  content: T,
  next: Option<Box<Node<T>>>
}

struct LinkedList<T> {
  first: Option<Box<Node<T>>>,
  size: i64
}

impl<T: std::default::Default + std::cmp::PartialEq> LinkedList<T> {
  fn new() -> Self {
    LinkedList { first: None, size: 0 }
  }

  fn push(&mut self, value: T) {
    let mut tmp_node = Box::new(Node { content: value, next: None });
    let old_first_node = std::mem::replace(&mut self.first, None);
    tmp_node.next = old_first_node;
    self.first = Some(tmp_node);

    self.size += 1;
  }

  fn pop(&mut self) -> Option<T> {
    let mut old_first = std::mem::replace(&mut self.first, None);
    match &mut old_first {
      None => {
        return None;
      },
      Some(ptr) => {
        self.first = std::mem::take(&mut ptr.next);
        let val_to_return = std::mem::take(&mut ptr.content);
        return Some(val_to_return);
      }
    }
  }

  fn remove(&mut self, value: T) {
    let mut current_node = &mut self.first;

    while let Some(node) = current_node {
      if node.content == value {
        *current_node = node.next.take();
        break;
      }
      current_node = &mut node.next;
    }
  }
}

fn main() {
  
}

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:

fn remove(&mut self, value: T) {
    let mut current_node = &mut self.first;

    while current_node.is_some() {
        if current_node.as_mut().unwrap().content == value {
            *current_node = current_node.as_mut().unwrap().next.take();
            break;
        }
        current_node = &mut current_node.as_mut().unwrap().next;
    }
}
英文:

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:

fn remove(&mut self, value: T) {
    let mut current_node = &mut self.first;

    while current_node.is_some() {
        if current_node.as_mut().unwrap().content == value {
            *current_node = current_node.as_mut().unwrap().next.take();
            break;
        }
        current_node = &mut current_node.as_mut().unwrap().next;
    }
}

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:

确定