简体   繁体   English

Rust 所有权 - 由于“位于共享引用后面”而无法移动

[英]Rust ownership - cannot move due to being “behind a shared reference”

I am learning Rust and practicing on Linked Lists, whereby I want to get to a solution that doesn't involve a .clone() at the end.我正在学习 Rust 并在链接列表上练习,因此我想找到一个最后不涉及.clone()的解决方案。

Here's the smallest useful MVP code I can come up with ( Rust Playground ):这是我能想到的最小的有用 MVP 代码( Rust Playground ):

#![allow(unused)]
fn main() {
    let v: Option<Box<ListNode>> = None;

    println!("{:?}", v);
    let result2 = get_nth_node(v, 3);
    println!("  --> {:?}", result2);
}

#[derive(PartialEq, Eq, Clone, Debug)]
pub struct ListNode {
    pub val: i32,
    pub next: Option<Box<ListNode>>
}

fn get_nth_node(head: Option<Box<ListNode>>, n:usize) -> Option<Box<ListNode>> {
    if head.is_none() {
        return None;
    }

    let mut count = 1;
    let mut ptr: &Option<Box<ListNode>> = &head;
    while count < n {
        count += 1;
        match ptr {
            None                    => return None,
            Some(v) => ptr = &v.next
        }
    }
    return (*ptr);
}

This yields an error on moving and borrowing:这会在移动和借用时产生错误:

error[E0507]: cannot move out of `*ptr` which is behind a shared reference
  --> src/main.rs:30:12
   |
30 |     return (*ptr);
   |            ^^^^^^
   |            |
   |            move occurs because `*ptr` has type `std::option::Option<std::boxed::Box<ListNode>>`, which does not implement the `Copy` trait
   |            help: consider borrowing the `Option`'s content: `(*ptr).as_ref()`

I understand why changing the function to return (*ptr).clone() works, but it seems superfluous.我理解为什么将 function 更改为 return (*ptr).clone()有效,但这似乎是多余的。

My two main questions: 1. What specifically is the shared reference that *ptr is behind?我的两个主要问题: 1. *ptr背后的共享引用具体是什么? 2. Is there a better way, conceptually, to work with this in Rust? 2. 从概念上讲,有没有更好的方法在 Rust 中使用它?

What specifically is the shared reference that *ptr is behind? *ptr 背后的共享引用具体是什么?

ptr is a shared (immutable) reference: ptr是共享(不可变)引用:

 let mut ptr: &Option<Box<ListNode>> = &head;

*ptr is behind that reference. *ptr在该引用的后面。

Is there a better way, conceptually, to work with this in Rust?从概念上讲,有没有更好的方法在 Rust 中使用它?

Well you could just not work with references since you're taking the list by value and are therefore consuming it:好吧,您不能使用引用,因为您按值获取列表并因此使用它:

fn get_nth_node(mut head: Option<Box<ListNode>>, n:usize) -> Option<Box<ListNode>> {
    let mut count = 1;
    while count < n {
        count += 1;
        match head {
            None                    => return None,
            Some(v) => head = v.next
        }
    }
    return head;
}

Alternatively, you could work with refs (that would probably be a better idea really):或者,您可以使用 refs (这可能是一个更好的主意):


fn get_nth_node(mut head: Option<&ListNode>, n:usize) -> Option<&ListNode> {
    let mut count = 1;
    while count < n {
        count += 1;
        match head {
            None                    => return None,
            Some(v) => head = v.next.as_ref().map(Box::as_ref)
        }
    }
    head
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM