I have a function passed to and_then
that returns a type not known to the compiler. When chained with other option methods, type annotations are required.
fn main() {
let w = Some("hi".to_string());
let x: Option<&String> = w.as_ref();
//fails:
let y: Option<String> =
x.and_then::<String, FnOnce(Option<&String>) -> Option<String>>(|_inner: &String| None);
//ok:
let y: Option<String> = x.and_then(|_inner: &String| None);
}
playground
Adding the mandatory annotations causes this compiler error:
error: the `and_then` method cannot be invoked on a trait object
--> src/main.rs:7:11
|
7 | x.and_then::<String, FnOnce(Option<&String>) -> Option<String>>(|_inner: &String| None);
| ^^^^^^^^
I assume it is complaining about the FnOnce
trait, but I don't see what this has to do with x
.
I would like to understand what is going wrong here.
Ultimately, the goal is to have this and_then
in a chained statement, which is why the annotations are needed.
let y = x
.and_then::<String, FnOnce(Option<&String>) -> Option<String>>(|_inner: &String| None)
.and(Some("new String".to_string()));
There are multiple problems here:
Closures are an anonymous type, which means that you cannot name them.
It's currently impossible to have a bare trait like FnOnce
because it is unsized.
|| foo
isn't a trait, it's a concrete type.
Instead, specify the return type of the closure:
let y = x
.and_then(|_inner| -> Option<String> { None })
.and(Some("new String".to_string()));
Or qualify the type of the None
:
let y = x
.and_then(|_inner| None::<String>)
.and(Some("new String".to_string()));
Or avoid the chaining:
let y: Option<String> = x.and_then(|_inner| None);
let y = y.and(Some("new String".to_string()));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With