我正在尝试在 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 图,但我无法找到使它们中的任何一个工作的方法,因为我通常会收到“共享引用”错误
您需要指定对父级引用的“生命周期”。像这样的东西:
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" })