此代码正确编译。它有一些未使用的代码警告,但现在没问题。
use std::collections::BTreeMap;
enum Object<'a> {
Str(String),
Int(i32),
Float(f32),
Vector(Vec<&'a Object<'a>>),
Prim(fn(State) -> State)
}
struct State<'a> {
named: BTreeMap<String, &'a Object<'a>>,
stack: Vec<Object<'a>>
}
impl<'a> State<'a> {
fn push_int(&mut self, x: i32) {
self.stack.push(Object::Int(x));
}
}
fn main() {
println!("Hello, world!");
let obj = Object::Str("this is a test".to_string());
}
此代码的重要部分是push_int
和stack: Vec<Object<'a>>
。
我正在尝试制作基于堆栈的VM。 我想将状态传递给函数,函数可以从堆栈中取出东西,操作东西,然后将一些东西放回堆栈;命名字段将保存命名对象。
我有一种预感,最好将堆栈表示为Vec<&'a Object<'a>>
。
我现在拥有它的方式,我担心我会犯一些效率低下的错误。我的预感是否正确?
问题的第二部分是我不知道如何使引用版本的矢量工作。使用合适的生命周期创建新值以推入堆栈对我来说不起作用。
我对这个问题有点模糊,所以如果我一直不清楚,请向我提问以清除问题。
答案 0 :(得分:7)
您无法使其工作的原因是结构不能包含引用其他字段的字段。 (参见底部的支持链接。)
您可以做的是将所有Object
放入Vec
,并使HashMap
包含其引用的命名元素的索引。
struct State {
named: BTreeMap<String, usize>,
stack: Vec<Object>
}
我还会从您的示例中删除所有生命周期,因为这可以使用拥有的对象完全完成。
enum Object {
Str(String),
Int(i32),
Float(f32),
Vector(Vec<Object>),
Prim(fn(State) -> State)
}
您可以在Playground
中试用有效的实施方案支持链接:
How to store HashMap and its Values iterator in the same struct?
What lifetimes do I use to create Rust structs that reference each other cyclically?
How to store a SqliteConnection and SqliteStatement objects in the same struct in Rust?
Why can't I store a value and a reference to that value in the same struct?
https://stackoverflow.com/questions/33123634/reference-inside-struct-to-object-it-owns