I am writing an interpreter for a Scheme-like language in Rust. I coded the AST as an enum:
#[derive(Debug)]
pub enum Object {
Integer(i64),
Boolean(bool),
Character(char),
String(String),
Symbol(String),
Cons { car: Box<Object>, cdr: Box<Object> },
Nil,
}
pub type ObjectBox = Box<Object>;
I wanted to add a car(&self) -> ObjectBox
method to Object
. I came up with:
impl Object {
pub fn car(&self) -> Option<ObjectBox> {
match self {
Object::Cons { car, cdr: _ } => Some(ObjectBox::new(**car)),
_ => None,
}
}
}
On compiling I get this error:
error[E0507]: cannot move out of `**car` which is behind a shared reference
--> src/core/object.rs:94:65
|
94 | Object::Cons { car, cdr: _ } => Some(ObjectBox::new(**car)),
| ^^^^^ move occurs because `**car` has type `object::Object`, which does not implement the `Copy` trait
For more information about this error, try `rustc --explain E0507`.
I understand why the error is happening, but I am unable to come up with a way to fix it. Can this be done with my current Object
implementation?
You cannot move out of a &self
, so you have few options:
self
:impl Object {
pub fn car(self) -> Option<ObjectBox> {
match self {
Object::Cons { car, cdr: _ } => Some(ObjectBox::new(*car)),
_ => None,
}
}
}
pub type ObjectBox<'a> = Box<&'a Object>;
impl Object {
pub fn car(&self) -> Option<ObjectBox> {
match self {
Object::Cons { car, cdr: _ } => Some(ObjectBox::new(car.as_ref())),
_ => None,
}
}
}
#[derive(Debug, Clone)]
pub enum Object {
Integer(i64),
Boolean(bool),
Character(char),
String(String),
Symbol(String),
Cons { car: Box<Object>, cdr: Box<Object> },
Nil,
}
pub type ObjectBox = Box<Object>;
impl Object {
pub fn car(&self) -> Option<ObjectBox> {
match self {
Object::Cons { car, cdr: _ } => Some(ObjectBox::new(*car.clone())),
_ => None,
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.