何时以及如何使用引用向量

phi*_*hil 6 reference vector rust

此代码正确编译.它有一些未使用的代码警告,但现在没问题.

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());
}
Run Code Online (Sandbox Code Playgroud)

这段代码的重要部分是push_int和stack: Vec<Object<'a>>.

我正在尝试制作基于堆栈的VM.我想将状态传递给函数,函数可以从堆栈中取出东西,操作东西,然后将一些东西放回堆栈; 命名字段将保存命名对象.

我有一种预感,将堆栈表示为Vec<&'a Object<'a>>替代会更好.我现在拥有它的方式,我担心我会犯一些效率低下的错误.我的预感是正确的吗?

问题的第二部分是我不知道如何使引用版本的矢量工作.以适当的生命周期创建新值以推入堆栈对我来说不起作用.

我对这个问题有点模糊,所以如果我一直不清楚,请问我问题以清除问题.

oli*_*obk 7

您无法使其工作的原因是结构不能包含引用其他字段的字段.(参见底部的支持链接.)

你可以做的是将所有Objects放入你的Vec,并HashMap包含它引用的命名元素的索引.

struct State {
    named: BTreeMap<String, usize>,
    stack: Vec<Object>
}
Run Code Online (Sandbox Code Playgroud)

我还将从您的示例中删除所有生命周期,因为这可以使用拥有的对象完全完成.

enum Object {
    Str(String),
    Int(i32),
    Float(f32),
    Vector(Vec<Object>),
    Prim(fn(State) -> State)
}
Run Code Online (Sandbox Code Playgroud)

您可以在Playground中尝试一个有效的实现

支持链接:

  • 关于"(是的,每个单词是不同的链接)"的样式点.其他Stack Overflow问题链接的项目符号列表更易于浏览,因为SO会自动查找标题并显示它们. (2认同)