我正在使用编译器插件构建一个惰性表达式求值程序like Python's。
我想打印一个日志:
assert ( left == vec![1, 2, 3, 4] )
assert ( vec![1, 2, 3, 4] == vec![1, 2, 3, 4] );
并尝试:
// crate rt
pub struct Expr<T, F: FnMut() -> T> {
// I noticed that this must be changed to fn with format!() call, to
// support updating child.
src: &'static str, // holds value
}
pub trait EvalTo: Display {
/// Type of expression
type Type;
/// Returns Some(val) when done
/// Accepts &mut self as it might be called many time.
fn eval_one_level(&mut self) -> Some<T>;
}
impl<T, F> EvalTo for Expr<T, F> {
type Type = T;
}
/// Prints source before evaluation, (it must be changed)
/// and value after evaluation.
impl<T, F> Display for Expr<T, F> {}
使用编译器插件在编译时创建它们。但是当我做的时候
let left = vec![1, 2, 3, 4];
lazy_expr!(left == vec![1, 2, 3, 4]);
它扩展到
::rt::binary({
::rt::Expr::wrap(::rt::Source{ expr: "left" }, || Some(left))
}, {
::rt::Expr::wrap(::rt::Source{ expr: "vec!(1, 2, 3, 4)" },
|| vec![1, 2, 3, 4])
}).eq()
并且编译器不喜欢它。它说cannot move out of captured outer variable in an `FnMut` closure
。
所以我不能使用FnMut
,但需要多次调用它,并且需要能够修改子表达式。
是否存在允许捕获局部变量的数据结构,但是可以使用&mut self
多次调用?我应该使用FnOnce(&mut Context)
吗?
答案 0 :(得分:0)
我不再需要这个,因为我使用了另一个apporach。但为了完成,您可以使用(&mut self)
定义特征并使用
[std::mem::replace
] []获取自有值,Option
有一个名为.take()
的辅助方法。
对于谁想要使用编译器插件构建延迟可评估引擎,我did some more on compile time。
它叫
fn capture<T :?Sized>(&mut self, expr: &'static str, val: &T)
来自生成的代码,如
ctx.capture("f()", &_var_of_expr)
因此上下文可以用它来表达表达式和值。