可选择引用父结构

问题描述 投票:0回答:1

我正在尝试在 Rust 中实现一个可以包含值的“范围”。它可以选择有一个父作用域,如果父作用域包含该值但它不包含该值,则它可以查找该父作用域。

作用域需要传递给许多其他函数。假设我有以下代码:

use std::collections::HashMap;

struct Value {
    value: String,
}

struct Scope {
    values: HashMap<String, Value>,
    parent: Option</* ??? */>,
}

impl Scope {
    fn new() -> Scope {
        Scope {
            values: HashMap::new(),
            parent: None,
        }
    }

    fn new_with_parent(scope: /* ??? */) -> Scope {
        Scope {
            values: HashMap::new(),
            parent: Some(scope),
        }
    }

    pub fn add_value(&mut self, name: String, val: Value) -> () {
        self.values.insert(name, val);
    }

    pub fn get_parent_value(&mut self, name: String) -> Value {
        match self.parent {
            None => Value {
                value: "None".to_string(),
            },
            Some(parent) => panic!()
        }
    }
}

fn main() {
    let mut scope = Scope::new();
    scope.add_value(
        String::from("test"),
        Value {
            value: "test".to_string(),
        },
    );

  test(&mut scope);
}

fn test(scope: &mut Scope) -> Value {
  let mut child = Scope::new_with_parent(&scope);
  child.get_parent_value(String::from("test"))
}

这是我正在尝试做的一个最小示例,我只是不知道要使用哪种类型以及如何使用它。

我不确定这是否是在 Rust 中做这样的事情的正确方法,但我想不出其他任何东西,因为我对此很陌生。

我尝试过使用

Box::pin
*const
RefCell
使用 Pin 图,但我无法找到使它们中的任何一个工作的方法,因为我通常会收到“共享引用”错误

rust struct reference parent
1个回答
0
投票

您需要指定对父级引用的“生命周期”。像这样的东西: use std::collections::HashMap; #[derive(Debug)] struct Value { _value: String, } impl Value { fn new(value: &str) -> Self { Self { _value: value.to_string() } } } struct Scope<'a> { values: HashMap<String, Value>, parent: Option<&'a Scope<'a>>, } impl<'a> Scope<'a> { fn new(parent: Option<&'a Scope>) -> Scope<'a> { Scope { values: HashMap::new(), parent, } } pub fn add_value(&mut self, name: &str, val: Value) { self.values.insert(name.to_string(), val); } pub fn get_value(&self, name: &str) -> Option<&Value> { self.values.get(name) } pub fn get_parent_value(&self, name: &str) -> Option<&Value> { match self.parent { Some(scope) => scope.get_value(name), None => None } } } fn main() { let mut parent = Scope::new(None); parent.add_value("parent_name", Value::new("parent_value")); let mut child = Scope::new(Some(&parent)); child.add_value("child_name", Value::new("child_value")); println!("child value: {:?}", child.get_value("child_name")); println!("parent value: {:?}", child.get_parent_value("parent_name")); }

输出:

child value: Some(Value { _value: "child_value" }) parent value: Some(Value { _value: "parent_value" })

铁锈游乐场

© www.soinside.com 2019 - 2024. All rights reserved.