What is the intended type of closure vector?

I tried to create a closure vector like this:

fn main() { let mut vec = Vec::new(); vec.push(Box::new(||{ 10 })); vec.push(Box::new(||{ 20 })); println!("{}", vec[0]()); println!("{}", vec[1]()); } 

This gave the following error report:

 error: mismatched types: expected `[closure RustTest.rs:4:20: 4:28]`, found `[closure RustTest.rs:5:20: 5:28]` (expected closure, found a different closure) [E0308] RustTest.rs:5 vec.push(Box::new(||{ 20 })); ^~~~~~~~ 

I fixed it by explicitly specifying the type:

 let mut vec: Vec<Box<Fn() -> i32>> = Vec::new(); 

So my question is: what is the vec type vec and why is it like that?

+6
source share
1 answer

Each closure has an oscillator, a unique, anonymous type. As soon as you add the first closure to the vector, this is the type of all elements in the vector. However, when you try to add a second closure, it has another autogenerator, a unique anonymous type, and therefore you get the error indicated.

Closures are essentially struct that are created by a compiler that implements one of the Fn* traits. struct contains fields for all variables captured by the closure, therefore, by definition, it must be unique, since each closure will capture different numbers and types of variables.

Why can't he conclude Box<Fn() -> i32> ?

β€œcannot” is a difficult question to answer. It is possible that the compiler could iterate over all the traits of each type, which are used to see if some kind of intersection led the code to compile, but for me it is a little worried. You can try opening a feature request or discussing it in one of the forums to see if there is any acceptance of such an idea.

However, Rust tries to make things explicit, especially things that may include performance. When you move from a specific structure to a feature object, you enter an indirect direction that can be slower.

Right now, the Fn* traits work just like a custom tag:

 trait MyTrait { fn hello(&self) {} } struct MyStruct1; impl MyTrait for MyStruct1 {} struct MyStruct2; impl MyTrait for MyStruct2 {} fn main() { let mut things = vec![]; things.push(MyStruct1); things.push(MyStruct2); } 
+4
source

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


All Articles