这段代码正确编译。虽然有一些未使用的代码警告,但目前来说可以忽略。
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>>
。我正在尝试制作一个基于堆栈的虚拟机。 我想把状态传递给函数,这些函数可以从堆栈中取出一些东西,操作它们,然后把一些东西放回到堆栈中;命名字段将保存有命名对象。
我有一种直觉,最好将堆栈表示为
Vec<&'a Object<'a>>
。现在我担心自己犯了一些效率上的错误。我的直觉正确吗?问题的第二部分是我不知道如何让引用向量版本工作。创建具有正确生命周期的新值以推送到堆栈上对我来说行不通。
关于这个问题我有点模糊,如果我表述不清楚,请问我一些问题以澄清事情。
Vec<Box<Object<'a>>>
。存在效率问题,因为Object :: Int
占用的空间与Object :: String
相同,但将其封装只会使情况更糟(即使封箱允许更紧凑的表示方式)。 我会将Str(String)
更改为Str(Box<String>)
,将Vector<Vec<...>>
更改为Vector<Box<Vec<...>>>
,然后就可以了,因为这样可以消除使Object
太大的唯一因素。 尽管如此,对于更小的(可能更常见的)值来说,额外的间接性可能比低效性更糟糕。 - Veedrac