关于rust 所有权转移与Option中的take()方法的疑问?

这是leetcode中的206反转链表,问题如代码中的注释所示,prev = curr会转移curr的所有权,但后面又能给curr赋值,而let mut next = node.next(不加.take())转移node.next的所有权后,node.next却不能再使用,也就是在node.next = prev时会提示node.next已经被移动

// Definition for singly-linked list.
// #[derive(PartialEq, Eq, Clone, Debug)]
// pub struct ListNode {
//   pub val: i32,
//   pub next: Option<Box<ListNode>>
// }
// 
// impl ListNode {
//   #[inline]
//   fn new(val: i32) -> Self {
//     ListNode {
//       next: None,
//       val
//     }
//   }
// }
impl Solution {
    pub fn reverse_list(head: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
        let mut prev = None;
        let mut curr = head;
        while let Some(ref mut node) = curr {
            let mut next = node.next.take();    // 为什么这里需要take(),而下面的prev = curr却不需要呢
            node.next = prev;
            prev = curr;    // 由于 curr 是可变的,所以即使这里转移所有权后,它依然可以用下面的语句修改?
            curr = next;
        }
        prev
    }
}
阅读 460
1 个回答

没有 take 的话:

Line 22: Char 28: error: cannot move out of `node.next` which is behind a mutable reference (solution.rs)
   |
22 |             let mut next = node.next;    // 为什么这里需要take(),而下面的prev = curr却不需要呢
   |                            ^^^^^^^^^ move occurs because `node.next` has type `Option<Box<list_node::ListNode>>`, which does not implement the `Copy` trait
   |
help: consider borrowing here
   |
22 |             let mut next = &node.next;    // 为什么这里需要take(),而下面的prev = curr却不需要呢
   |                            +
help: consider cloning the value if the performance cost is acceptable
   |
22 |             let mut next = node.next.clone();    // 为什么这里需要take(),而下面的prev = curr却不需要呢
   |                                     ++++++++

For more information about this error, try `rustc --explain E0507`.
error: could not compile `prog` (bin "prog") due to 1 previous error

这里是不能转移所有权的,因为 node 是一个 borrow 。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏