Expected opaque type, found a different opaque type problem

Hi, I'm trying to do a parser generator and to do that I have a function that take in a Vec<Fn(&str) -> Result<(ParserReturn, &str), &str>> where the Fn(&str) -> ... don't come from the same place. However, it won't let me create that Vec and says expected opaque type, found a different opaque type From what I understood, when a function return a impl fn... it is a unique type so we can't create a Vec of them. Anyone know how can I manage to create a Vec like that. I don't think that i explained well the problem so tell me if you need more precises informations to help me. Thanks

Hi there!
Since your functions in your Vec are not homogenous in type (ie they do not all have the same type), you need a way to abstract away what the actual function is and put it under one type.

The usual way of doing this is called dynamic dispatch, where the type of the function is abstracted away under a very broad "is a function" (aka dyn Fn(&str) -> Result<...>). Since the size of this type is unknown (since not all things that implement a function interface are of the same size: capturing closures vs non capturing closures), you need to put it under some kind of indirection. Hence you can do this:

let x = Box::new(|y| { println!("{:?}", y) }) as Box<dyn Fn(&str)>;

x's type carries no information on what the function actually is. It is deduced at runtime. Which comes with the drawback of the double indirection to actually call the function, therefore dynamic dispatch is slightly slower than calling the function directly.

You could also make an enum to represent either a function pointer (Something that captures no environment) or a Boxed closure (what I just discussed).

Thank you so much for the help I think it worked :ok_hand:

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.