Reputation: 703
I'm getting confused by this. If the following works:
fn func_exit() -> bool {
println!("hi");
true
}
fn locate_func() -> fn() -> bool {
func_exit
}
Why these following syntaxes throw error?
fn locate_func1<F: Fn() -> bool>() -> F {
func_exit
}
fn locate_func2<F>() -> F where F:Fn() -> bool {
func_exit
}
I'm new to Rust and the following error message is not clear to me:
error[E0308]: mismatched types
--> src/main.rs:44:9
|
43 | fn locate_func1<F: Fn() -> bool>() -> F {
| - this type parameter - expected `F` because of return type
44 | func_exit
| ^^^^^^^^^ expected type parameter `F`, found fn item
|
= note: expected type parameter `F`
found fn item `fn() -> bool {func_exit}`
= help: type parameters must be constrained to match other types
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
error[E0308]: mismatched types
--> src/main.rs:47:9
|
46 | fn locate_func2<F>() -> F where F:Fn() -> bool {
| - - expected `F` because of return type
| |
| this type parameter
47 | func_exit
| ^^^^^^^^^ expected type parameter `F`, found fn item
|
= note: expected type parameter `F`
found fn item `fn() -> bool {func_exit}`
= help: type parameters must be constrained to match other types
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
Appreciate some help. Thanks
Upvotes: 0
Views: 74
Reputation: 42492
The error is weird, but... you can't just return a bounded value like this, because bounded types are decided by the caller, and it doesn't make sense for the caller to decide what the return type is unless that return type is a consequence of an input type (e.g. an identity function is a trivial example of this). Which is not the case here.
If you want to return something generic, you need either some sort of trait object (so e.g. box the function and return a Box) or an impl
(which still has a concrete return value but hides it at the API level).
The latter is more efficient but only allows returning a single concrete type, the former is less efficient but lets you return e.g. different closures.
Upvotes: 1
Reputation: 36031
fn locate_func() -> fn() -> bool {
func_exit
}
locate_func
returns a pointer to a function returning bool (i.e. fn() -> bool
).
fn locate_func1<F: Fn() -> bool>() -> F {
func_exit
}
locate_func1
means that the caller can specify any F
satisfying the bounds Fn() -> bool
, and it will return an F
. But it is clearly not the case that func_exit
is necessarily of the type specified by the caller.
locate_func2
has the same problem, just with where
-Notation.
What you probably want could be the following:
fn locate_func3() -> impl Fn() -> bool {
func_exit
}
It says: locate_func3
returns something that implements the bound Fn() -> bool
(and func_exit
does so, so it can be returned there).
Also note the difference between fn
(function pointers) and Fn
("something callable"):
Upvotes: 3