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

后端 未结 2 1833
离开以前
离开以前 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;
    }
    
    impl MyThings for Option {
        fn more_optional(self) -> Option> {
            Some(self)
        }
    }
    
    fn main() {
        let x = Some(1);
        let y = x.more_optional();
        println!("{:?}", y);
    }
    

    For flatten, I'd probably write:

    fn flatten(opt: Option>) -> Option {
        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 {
        fn flatten(self) -> Option;
    }
    
    impl MyThings for Option> {
        fn flatten(self) -> Option {
            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?

提交回复
热议问题