How can I "add" a flatten()
method to Option<U>
, which would only typecheck if and only if U
is an Option<T>
, or more simply to add it to Option<Option<T>>
? Naively, I am trying to write the following, which doesn't compile:
impl Option<Option<T>> {
fn flatten(&self) -> Option<T> {
match self {
None => None,
Some(v) => v,
}
}
}
fn main() {
let x = Some(Some(1));
let y = x.flatten();
println!("{:?}", y);
}
You can't write inherent implementations (what you're trying) to types you didn't define, due to coherence (if you could, how do you know someone else hasn't also defined something called flatten
?).
Instead, you need to define and implement a trait with the method you want. Anywhere you want the method, you use the trait:
trait Flatten<T> {
fn flatten(self) -> Option<T>;
}
impl<T> Flatten<T> for Option<Option<T>> {
fn flatten(self) -> Option<T> {
match self {
None => None,
Some(v) => v,
}
}
}
fn main() {
let x = Some(Some(1));
let y = x.flatten();
println!("{:?}", y);
}
Also note that I changed the subject of the method from &self
to self
: you can't move out of a borrow (especially not an immutable one), so taking self
by reference doesn't really make sense here.
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