Je construis un évaluateur d'expressions paresseux like Python's en utilisant un plugin de compilateur.Conception de structures de données pour un évaluateur paresseux enfant-premier qui imprime la procédure
Je veux imprimer un journal comme:
assert (left == vec![1, 2, 3, 4])
assert (vec![1, 2, 3, 4] == vec![1, 2, 3, 4]);
et essayé:
// 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> {}
avec le plugin compilateur pour les créer sur la compilation. Mais quand je fais
let left = vec![1, 2, 3, 4];
lazy_expr!(left == vec![1, 2, 3, 4]);
Il se développe pour
::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()
et le compilateur ne l'aime pas. Il est dit cannot move out of captured outer variable in an `FnMut` closure
.
Je ne peux donc pas utiliser FnMut
, mais il doit être appelé plusieurs fois et doit pouvoir modifier l'expression enfant.
Existe-t-il une structure de données permettant de capturer des variables locales, mais pouvant être appelée plusieurs fois avec &mut self
? Dois-je utiliser FnOnce(&mut Context)
?
Veuillez générer un [MCVE]. Il est très peu probable que quelqu'un va également créer un plugin de compilation juste pour essayer de reproduire votre erreur. Idéalement, faites quelque chose qui peut [courir sur le terrain de jeu] (https://play.rust-lang.org/). Encore mieux, [passez en revue les ** 7 autres questions avec le même message d'erreur **] (http://stackoverflow.com/search?q=cannot+move+out+of+captured+outer+variable+in+an+ FnMut + closure + est% 3Aq) * avant * demande. Ensuite, expliquez pourquoi * cette question * est différente de * ces questions *. – Shepmaster
J'ai décidé de faire quelque chose comme http://pybites.blogspot.kr/2011/07/behind-scenes-of-pytests-new-assertion.html parce que je ne peux pas représenter ast avec générique et cette question devient inutile pour moi . – kdy
@Shepmaster Ceci est une question sur la conception, et ces questions portent sur l'utilisation de FnMut. Je n'essaie pas de faire passer la valeur à la fermeture. Au lieu de cela, je voulais faire quelque chose comme permettre à la fois FnOnce et FnMut. Et j'ai trouvé que cela peut être fait via [futures-rs] (http://alexcrichton.com/futures-rs/futures/index.html) – kdy