diff --git a/examples/callback.rs b/examples/callback.rs index 40791bcd..ce27f77c 100644 --- a/examples/callback.rs +++ b/examples/callback.rs @@ -2,33 +2,41 @@ use rhai::{Engine, EvalAltResult, FnPtr}; +// To call a Rhai closure at a later time, you'd need three things: +// 1) an `Engine` (with all needed functions registered), +// 2) a compiled `AST`, +// 3) the closure (of type `FnPtr`). fn main() -> Result<(), Box> { - // This script creates a closure which may capture variables. - let script = " - let x = 20; - - // The following closure captures 'x' - return |a, b| (x + a) * b; - "; - - // To call a Rhai closure at a later time, you'd need three things: - // 1) an `Engine` (with all needed functions registered), - // 2) a compiled `AST`, - // 3) the closure (of type `FnPtr`). let engine = Engine::new(); - let ast = engine.compile(script)?; + // This script creates a closure which captures a variable and returns it. + let ast = engine.compile( + " + let x = 18; + + // The following closure captures 'x' + return |a, b| { + x += 1; // x is incremented each time + (x + a) * b + }; + ", + )?; let closure = engine.eval_ast::(&ast)?; - // Create a closure that we can call any time, encapsulating the - // `Engine`, `AST` and `FnPtr`. - let func = move |x: i64, y: i64| -> Result { closure.call(&engine, &ast, (x, y)) }; + // Create a closure by encapsulating the `Engine`, `AST` and `FnPtr`. + // In a real application, you'd be handling errors. + let func = move |x: i64, y: i64| -> i64 { closure.call(&engine, &ast, (x, y)).unwrap() }; // Now we can call `func` anywhere just like a normal function! - let result = func(1, 2)?; + let r1 = func(1, 2); - println!("The Answer: {}", result); // prints 42 + // Notice that each call to `func` returns a different value + // because the captured `x` is always changing! + let r2 = func(1, 2); + let r3 = func(1, 2); + + println!("The Answers: {}, {}, {}", r1, r2, r3); // prints 40, 42, 44 Ok(()) }