fn main(){
let x = "sam".to_string();
let y: impl FnOnce() -> String = || x;
}
Here i'm using a closure , where the compile is infering a impl trait rather than a type. According to rust book, a closure is a anonymous function. And we can only apply trait to type. On what basis compiler is infering like this?
The types of closures (and function items too) are anonymous types you can't name. As such you can only refer to them by their properties, namely implementing a trait, and usually the ones you care for closures are the Fn* traits.
I want to to know the return types of closure in general. According to my knowledge closure is anonymous function. Im not concerned about * the code doesn't compile;. I just want to know how compiler is infering a trait for closure
The type of a closure is an anonymous, struct-like type, of which the "fields" contain captured environment, and callability is provided by the compiler implementing the applicable Fn* traits (FnOnce, FnMut, and/or Fn).
I still don't get that part. There was no "inference" in anything we talked about this thread so far.
The IDE is not the compiler. That hint is only your IDE trying to be "helpful" and show you something in place of the unnameable type, and you are misinterpreting its hint (or taking it too literally). (Which is one of many reasons for not using any sort of IDE especially while you are a beginner.)
The compiler doesn't infer the type of y to literally be impl FnOnce() -> String or whatever. The compiler creates its own internal type and that's what the type of the closure is.
impl Trait is merely a construct for naming capabilities of a type without having to name the type itself, which is helpful if the type cannot be named (like closures) or would be too verbose (as in the case of deeply-nested iterator adapters) or you intentionally want to hide the concrete type for API stability. It's a placeholder for a concrete type. Returning an impl Trait from a function does not change the concrete type of the returned value – it's just that the caller won't know what it is, only what trait(s) it implements.