带引用的嵌套结构

标签 nested rust

我有一些嵌套结构,无法创建对父结构的反向引用。安example :

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

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

    fn hello_world(&self) -> String {
        self.parent.hello().to_owned() + " world"
    }
}

struct Bar<'b> {
    child: Option<Foo<'b>>,
    data: &'static str,
}

impl<'b> Bar<'b> {
    fn new() -> Self {
        Bar {
            child: None,
            data: "hello",
        }
    }

    fn hello(&self) -> &str {
        self.data
    }

    fn get_foo(&self) -> Option<&Foo> {
        self.child.as_ref()
    }
}

fn main() {
    let bar = Bar::new();
    assert_eq!("hello", bar.hello());
    match bar.get_foo() {
        Some(foo) => assert_eq!("hello world", foo.hello_world()),
        None => (),
    }
}

如何替换 NoneSome<Foo>引用Bar ?到目前为止我还不确定这是否可能。

最佳答案

这并不完全是您示例的直接解决方案,但我相信您可以使用 ArcRwLock 创建指定的“循环引用”。 API 不完全相同(例如,parent 是一个可选字段),我重命名了一些对象,它肯定更冗长,但您的测试通过了!

use std::sync::{Arc, RwLock};

#[derive(Debug, Clone)]
struct Child {
    parent: Option<Arc<RwLock<Parent>>>
}

impl Child {
    fn new() -> Self {
        Child {
            parent: None
        }
    }

    fn hello_world(&self) -> String {
        let x = self.parent.as_ref().unwrap().clone();
        let y = x.read().unwrap();
        y.hello().to_owned() + " world"
    }
}

#[derive(Debug, Clone)]
struct Parent {
    child: Option<Arc<RwLock<Child>>>,
    data: &'static str
}

impl Parent {
    fn new() -> Self {
        Parent {
            child: None,
            data: "hello"
        }
    }

    fn hello(&self) -> &str {
        self.data
    }

    fn get_child(&self) -> Option<Arc<RwLock<Child>>> {
        self.child.as_ref().map(|x| x.clone() )
    }


}

fn main() {
    let parent = Arc::new(RwLock::new(Parent::new()));
    let child = Arc::new(RwLock::new(Child::new()));

    parent.write().unwrap().child = Some(child.clone());
    child.write().unwrap().parent = Some(parent.clone());

    assert_eq!("hello", parent.read().unwrap().hello());

    {
        let x = parent.read().unwrap();
        match x.get_child() {
            Some(child) => { assert_eq!("hello world", child.read().unwrap().hello_world()); }
            None => {},
        }
    }

}

关于带引用的嵌套结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39705896/

相关文章:

Python Sqlalchemy - 表名作为变量

asynchronous - rust-tokio 流中的缓冲区有没有办法使用 &[u8] 以外的东西?

unit-testing - 如何编写用于测试 Rust 模块的函数 stub ?

types - Rust 中的 Some 和 Option 有什么区别?

rust - 在泛型函数内的 `as` 表达式中使用类型参数

java - 嵌套 for 循环整数比较 - 意外索引

php - 正则表达式 - 忽略引号内的转义字符

javascript - 检查数组对象中的输出是否有 'error' 并在 'error' 中显示消息

c - 如何处理嵌套列表?

rust - 在 Rust 中使用 from_iter 创建 BTreeSet