This code correctly compiles. It has a few unused code warnings, but that's okay for now.
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());
}
The important part of this code is push_int
and stack: Vec<Object<'a>>
.
I'm sort of trying to make a stack-based VM. I want to pass the state to functions, which can take stuff off the stack, manipulate the stuff, and then put some stuff back on the stack; the named field is going to hold named objects.
I have a hunch that it would be better to have the stack represented as a Vec<&'a Object<'a>>
instead.
The way I have it now, I fear I'm committing some inefficiency error. Is my hunch correct?
The second part of the problem is that I don't know how to get the vector of references version to work. Creating new value with the right lifetimes to push onto the stack is not working for me.
I'm a bit vague about this issue, so if I've been unclear, ask me questions to clear stuff up.
The reason you could not get it to work is that structs cannot have fields that refer to other fields. (See supporting links at the bottom.)
What you can do, is put all the Object
s into your Vec
, and have the HashMap
contain the indices of the named elements it references.
struct State {
named: BTreeMap<String, usize>,
stack: Vec<Object>
}
I'd also remove all lifetimes from your example, as this can be done completely with owned objects.
enum Object {
Str(String),
Int(i32),
Float(f32),
Vector(Vec<Object>),
Prim(fn(State) -> State)
}
You can try out a working implementation in the Playground
Supporting links:
How to initialize struct fields which reference each other
using self in new constructor
How to design a struct when I need to reference to itself
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With