【问题标题】:Mutable borrow in RustRust 中的可变借用
【发布时间】:2019-10-12 03:28:54
【问题描述】:

我是 Rust 的新手,我只是在做一些练习。 有一个链表。例如 0->1->2->3->4,在索引 2 处将其截断,然后将两者反转,然后组合它们。 => 0 3 => 2->1->0->4->3

#[derive(debug)]
struct Node{
    val: usize,
    next: Option<Box<Node>>,
}

impl Node {
    fn new(i: usize) -> Node {
    ...
    }

    fn reverse_at(self, k: usize) -> Box<Node> {
        let mut prev = None;
        let mut curr = Box::new(self);

        let first_part_tail = &mut curr;

        let mut i: usize = 0;
        while i <= k {
            let next = curr.next.take();
            curr.next = prev;
            match next {
                Some(next_node) => {
                    prev = Some(curr);
                    curr = next_node;
                }
                None => return curr,
            }
            i += 1;
        }

        let head = prev.unwrap();
        prev = None;
        loop {
            let next = curr.next.take();
            curr.next = prev;
            match next {
                Some(next_node) => {
                    prev = Some(curr);
                    curr = next_node;
                }
                None => {
                    first_part_tail.next = Some(curr);
                    return head;
                }
            }
        }
    }
}

我需要获取第一个节点0的可变借用,获取到最后一个节点后设置0.next=44

在函数的末尾。但是节点0 的所有权已经发送给节点1。 显然,error[E0499]: cannot borrow `curr.next` as mutable more than once at a time 发生了,我不知道该怎么办。这让我困扰了很长时间。请帮忙。

play.rust-lang.org/...

&amp;,我想这个函数会改变节点本身。而且我不知道如何将自引用更改为新节点,所以我使用了self。如果有人可以修改它,那也有帮助。 也许,把这个函数改成

fn reverse_at(&mut self, k:usize){
    ...
}

【问题讨论】:

  • 在 Rust 游乐场 (play.rust-lang.org) 中包含一个带有 main 的完整示例可能会有所帮助。我开始查看并注意到您在方法签名中的 self 之前缺少 &amp; 。见:doc.rust-lang.org/1.30.0/book/2018-edition/…
  • @Ultrasaurus 我已经添加了游乐场链接。 &amp;,我想这个函数会改变节点本身。而且我不知道如何将自引用更改为新节点,所以我使用了self。如果有人可以修改它,那也有帮助。
  • 与您的错误无关,我看不到您的程序如何创建链接列表...请参见仅使用“new”play.rust-lang.org/… 的操场示例
  • 我发现了这个非官方的 rust 学习资源,里面有很多可能有用的链表示例:rust-unofficial.github.io/too-many-lists
  • @Ultrasaurus 结构节点来自其他东西。只需Node::new(1234),这将创建一个链表,4->3->2->1->None。 Node::new(1) 将创建 1-> 无。我去看看学习资源,谢谢。

标签: rust


【解决方案1】:

@Ultrasaurus 感谢学习资源https://rust-unofficial.github.io/too-many-lists/。现在我解决了这个问题,虽然它需要一些时间。

最终代码在这里playground

有点奇怪,我的LinkedNumber.headNode,因为LinkedNumber 总是有一个头,可能是零,但不是空的。也许应该是Box&lt;Node&gt;

在第 71 行,我使用ptr::read,它会

src 读取值而不移动它。

mem::take 也可以。但它需要用trait Default 的默认值初始化Node

我使用Box::new 将节点从堆栈移动到堆中。 (没有必要这样做,如果LinkedNumber.headBox&lt;Node&gt;

在第 73 行,标记头部的 raw_pointer *const Node

在第 94 行,如果链接一分为二,则将 *const Node 转换为 *mut Node,取消引用,将 (*ptr).next 设置为原始链接的最后一个节点。

如何测试:在第171行更改num.reverse_at(3)中的数字,它可以正常工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-12
    • 1970-01-01
    • 2022-01-11
    • 2016-07-30
    • 1970-01-01
    相关资源
    最近更新 更多