如何解决“返回引用当前函数拥有的数据的值”(结构之间的实际依赖关系)

保6b

我正在学习 Rust(我是 C++ 开发人员),但我仍然习惯于借用检查器。我有以下示例(也在 Godbolt 上:https ://godbolt.org/z/z873x9cPn ):

struct Foo {
    value: i32,
}

struct Bar <'a> {
    foo: &'a mut Foo,
}

struct Parent <'a> {
    foo: Foo,
    bar: Bar<'a>,
}

impl <'a> Bar <'a> {
    fn new(foo: &'a mut Foo) -> Self {
        Self {
            foo
        }
    }
}

impl <'a> Parent <'a> {
    fn new() -> Self {
        let mut foo = Foo{ value: 2};
        let bar = Bar::new(&mut foo);

        Self {
            foo,
            bar,
        }
    } 
}

fn main () {
    let _parent = Parent::new();
}

但是在尝试编译时出现错误:

error[E0515]: cannot return value referencing local variable `foo`
  --> <source>:27:9
   |
25 |           let bar = Bar::new(&mut foo);
   |                              -------- `foo` is borrowed here
26 | 
27 | /         Self {
28 | |             foo,
29 | |             bar,
30 | |         }
   | |_________^ returns a value referencing data owned by the current function

我一直在浏览其他帖子,但它们并没有完全解决这种依赖关系。另外,我一直试图弄清楚该怎么做,但没有找到解决方案。

什么是最好的解决方案?

乔伊

如果您在 C++ 中以与在 Rust 中相同的方式实现这一点,那么您将有未定义的行为。Rust 实际上在这里拯救了你。

&mut foo创建对 function-local 的引用foo,但随后您进入 foo的新实例Parent,因此该引用不再有效。Rust 在编译时捕捉到了这一点。当有对它的引用时,您不能移动或删除一个值。

从实现复杂性的角度来看,解决这个问题的最简单方法是使用引用计数智能指针 ( ) Rc它将授予BarParent 共享. Foo(这类似于 C++std::shared_ptr模板,并且具有几乎相同的语义。)

但是,由于您放弃Foo. Rust 不允许你获得对 an 持有的值的可变引用,Rc除非此时只有一个 Rc存在。

你可以用Cellor来解决这个问题RefCell,它提供了内部可变性RefCell更灵活但有更多的运行时开销,因为它在运行时实现了 Rust 的借用规则,这意味着如果你不正确地使用它也会出现恐慌。

这就是它的样子:

use std::rc::Rc;
use std::cell::RefCell;

struct Foo {
    value: i32,
}

struct Bar {
    foo: Rc<RefCell<Foo>>,
}

struct Parent {
    foo: Rc<RefCell<Foo>>,
    bar: Bar,
}

impl Bar {
    fn new(foo: Rc<RefCell<Foo>>) -> Self {
        Self {
            foo
        }
    }
}

impl Parent {
    fn new() -> Self {
        let mut foo = Rc::new(RefCell::new(Foo { value: 2 }));
        let bar = Bar::new(foo.clone());

        Self {
            foo,
            bar,
        }
    } 
}

由于您尝试创建的结构是自引用的,因此Rc处理此问题的非方法将涉及固定unsafe. 基本上,Foo在对它进行任何引用之前,您必须在一个稳定的内存位置创建它,并且Pin<_>需要确保一个值的内存位置永远不会改变。RefCell如果您希望值通过Parent和可变,您可能仍然需要Bar

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何解决Rust中的“返回引用当前函数拥有的数据的值”错误?

返回引用当前函数拥有的数据的值

从函数返回libusb :: Device的问题-尝试返回引用当前函数拥有的数据的值

如何避免filter_map()在Rust中出现错误“返回引用当前函数拥有的数据的值”?

Rust:返回一个引用当前函数拥有的数据的值

错误消息不清楚:返回引用当前函数拥有的数据的值

为什么在Rust中允许返回当前函数拥有的引用?

Entry :: Occupied.get()返回一个值,该值引用当前函数拥有的数据,即使hashmap应该具有所有权

Rust引用Vec当前函数错误拥有的数据

如何从函数返回拥有的数组?

Go:如何解决在两个包之间作为参数传递的结构的依赖关系?

如何解决“平面”数据结构中的逻辑依赖关系?

如何解决Maven插件中所有模块之间的依赖关系?

如何解决FormFlow中值之间的依赖关系冲突

如何解决依赖关系

为什么此函数返回(拥有的)值?

为什么我可以返回对函数拥有值的引用?

如果ffi函数修改了指针,是否应将拥有的结构引用为可变的?

使用线程和异步/等待时,如何解决“无法返回引用本地数据的值”?

函数内的ggplot不会返回带有数据点的散点图,而是返回带有数据帧值的散点图。如何解决这个问题?

如何解决共享库依赖关系?

堆栈如何解决依赖关系?

自制软件如何解决依赖关系?

rpm如何解决库依赖关系?

接口如何解决循环依赖关系?

如何解决dpkg依赖关系?

如何解决系统和库依赖关系之间的C ++冲突

如何存储用户拥有的数据?

显示当前登录用户拥有的数据