How to implement some convenient methods (e.g., flat_map, flatten) on Option?

后端 未结 2 1834
离开以前
离开以前 2020-12-21 11:21

It would be nice if Rust\'s Option provided some additional convenience methods like Option#flatten and Option#flat_map, where f

相关标签:
2条回答
  • 2020-12-21 11:48

    These probably already exist, just as different names to what you expect. Check the docs for Option.

    You'll see flat_map more normally as and_then:

    let x = Some(1);
    let y = x.and_then(|v| Some(v + 1));
    

    The bigger way of doing what you want is to declare a trait with the methods you want, then implement it for Option:

    trait MyThings {
        fn more_optional(self) -> Option<Self>;
    }
    
    impl<T> MyThings for Option<T> {
        fn more_optional(self) -> Option<Option<T>> {
            Some(self)
        }
    }
    
    fn main() {
        let x = Some(1);
        let y = x.more_optional();
        println!("{:?}", y);
    }
    

    For flatten, I'd probably write:

    fn flatten<T>(opt: Option<Option<T>>) -> Option<T> {
        match opt {
            None => None,
            Some(v) => v,
        }
    }
    
    fn main() {
        let x = Some(Some(1));
        let y = flatten(x);
        println!("{:?}", y);
    }
    

    But if you wanted a trait:

    trait MyThings<T> {
        fn flatten(self) -> Option<T>;
    }
    
    impl<T> MyThings<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);
    }
    

    Would there be a way to allow flatten to arbitrary depth

    See How do I unwrap an arbitrary number of nested Option types?

    0 讨论(0)
  • 2020-12-21 12:14
    fn flatten<T>(x: Option<Option<T>>) -> Option<T> {
        x.unwrap_or(None)
    }
    

    In my case, I was dealing with an Option-returning method in unwrap_or_else and forgot about plain or_else method.

    0 讨论(0)
提交回复
热议问题