gpt4 book ai didi

rust - 将 'borrow' 结构深深地移入其他对象的最佳方法是什么?

转载 作者:行者123 更新时间:2023-11-29 08:20:01 25 4
gpt4 key购买 nike

我正在研究一种以编程方式在内存中新建结构并将其附加到链表的方法。

我的做法是新建一个结构,新建一个指向它的框,然后用 Option 包装它。然后我需要将尾指针向下移动到新创建的指针。

我想让前一个节点拥有下一个节点。所以尾指针必须“借用”节点。

#[derive(Debug)]
struct S {
next: Option<Box<S>>,
}

#[cfg(test)]
mod test {
use crate::tmp::S;
use std::borrow::Borrow;

#[test]
fn test_tmp() {
let mut s1 = S { next: None };
let mut tail = &s1;
// potentially within a loop as a linked list has multiple nodes
{
let mut s2 = S { next: None };
s1.next = Some(Box::new(s2));
// tail = &s2;
tail = s1.next.as_ref().unwrap();
}
println!("s1: {:?}", &s1);
println!("tail: {:?}", &tail);
}
}

注释掉的行不起作用,因为所有者已移至 s1,我对此没有意见。

tail = &s2

它是如此丑陋,但下一行有效。假设我有一个深度包裹的结构并且我想借用它。这是否意味着我必须再次深入解开它?

tail = s1.next.as_ref().unwrap();

必须有一些方法可以做得更好。有什么提示吗?

最佳答案

是的,这是唯一的方法,但一点也不差。

当您将值插入链表时,您已经移动了该值的有效所有权(我说有效,因为 Box 只有有效拥有基础值,但在 Safe Rust 方面不直接拥有它)到最后一个节点。但是你是怎么做到的?搬家A进入B , 你还必须拥有 &mut B .而你只想得到一个 &A (或 &mut A )。你为什么不从 &mut B 得到它呢? , 反正你已经借过了?

我不明白“深度包裹”的真正含义。但假设我们有一个 head: S和一个 tail: &mut S , 其中tail借用head为首的链表的最后一个节点.现在,获取 tail 的更新引用搬家后new_tail进入tail ,您只需更改 tailtail.next (加上 OptionBox 解包代码,但这些不影响所有权)。

看看这个新的 Playground 代码:https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=1103d2f039c24ed6ea78408d613a4261

您应该使用 tail: &mut S 插入数据而不是来自 head .这就是链表的全部要点。所以要回答你的问题,是的,你必须从它的先例节点借用移动的节点,但无论如何你已经借用了先例节点,所以它没什么难看的。


实际上,我在那里作弊了。我偷偷调换了最后两个println!线。如果你把它们换回来,你会发现 &s1在最后一次使用 tail 之前不能使用,因为 tail可变地(因此排他性地)借用内部的东西 s1 .

error[E0502]: cannot borrow `s1` as immutable because it is also borrowed as mutable

那么如何解决这个问题呢?您不能直接执行此操作,因为如果线程在处理某些可变数据时发生困惑,您可能会以中毒数据告终。 This question还讨论了为什么不能重用可变引用。

您可能想使用 Cell 保存你想要制作的数据internally mutable with just an immutable borrow .但这会很棘手。或者,如果你想使用多线程,你可以尝试 Mutex .


但是撇开所有这些复杂性不谈,如果你想要真正的、直观的、快速的、低级的 Rust,你必须使用 Unsafe Rust。

关于rust - 将 'borrow' 结构深深地移入其他对象的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57517573/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com