Call closures from an array in Rust

How can I iterate over an array of closures each time calling them?

With the help of functions, I found that I can do this by simply going through the array and dereferencing the resulting values:

fn square(x: int) -> int { x * x } fn add_one(x: int) -> int { x + 1 } fn main() { let funcs = [square, add_one]; for func in funcs.iter() { println!("{}", (*func)(5i)); } } 

However, when I try to do the same with closing, I get an error message:

 fn main() { let closures = [|x: int| x * x, |x| x + 1]; for closure in closures.iter() { println!("{}", (*closure)(10i)); } } 

It produces:

 <anon>:4:24: 4:34 error: closure invocation in a `&` reference <anon>:4 println!("{}", (*closure)(10i)); ^~~~~~~~~~ note: in expansion of format_args! <std macros>:2:23: 2:77 note: expansion site <std macros>:1:1: 3:2 note: in expansion of println! <anon>:4:9: 4:41 note: expansion site <anon>:4:24: 4:34 note: closures behind references must be called via `&mut` <anon>:4 println!("{}", (*closure)(10i)); ^~~~~~~~~~ note: in expansion of format_args! <std macros>:2:23: 2:77 note: expansion site <std macros>:1:1: 3:2 note: in expansion of println! <anon>:4:9: 4:41 note: expansion site 

If I try to declare the iteration variable ref mut , it still doesn't work:

 fn main() { let closures = [|x: int| x * x, |x| x + 1]; for ref mut closure in closures.iter() { println!("{}", (*closure)(10i)); } } 

Results in:

 <anon>:4:24: 4:39 error: expected function, found `&|int| -> int` <anon>:4 println!("{}", (*closure)(10i)); ^~~~~~~~~~~~~~~ note: in expansion of format_args! <std macros>:2:23: 2:77 note: expansion site <std macros>:1:1: 3:2 note: in expansion of println! <anon>:4:9: 4:41 note: expansion site 

If I add another dereference:

 fn main() { let closures = [|x: int| x * x, |x| x + 1]; for ref mut closure in closures.iter() { println!("{}", (**closure)(10i)); } } 

I return to the original error:

 <anon>:4:24: 4:35 error: closure invocation in a `&` reference <anon>:4 println!("{}", (**closure)(10i)); ^~~~~~~~~~~ note: in expansion of format_args! <std macros>:2:23: 2:77 note: expansion site <std macros>:1:1: 3:2 note: in expansion of println! <anon>:4:9: 4:42 note: expansion site <anon>:4:24: 4:35 note: closures behind references must be called via `&mut` <anon>:4 println!("{}", (**closure)(10i)); ^~~~~~~~~~~ note: in expansion of format_args! <std macros>:2:23: 2:77 note: expansion site <std macros>:1:1: 3:2 note: in expansion of println! <anon>:4:9: 4:42 note: expansion site 

What am I missing here? Is there any documentation somewhere describing how this works?

+6
source share
1 answer

The .iter() vector method gives immutable links, you need to change them to cause a closure, so you should use .iter_mut() :

 fn main() { let mut closures = [|x: int| x * x, |x| x + 1]; for closure in closures.iter_mut() { println!("{}", (*closure)(10i)); } } ----- 100 11 
+7
source

Source: https://habr.com/ru/post/976568/


All Articles