rust - 如何在 Option 上实现一些方便的方法(例如 flat_map、flatten)?

标签 rust

如果 Rust 的 Option 就好了提供了一些额外的便利方法,例如 Option#flattenOption#flat_map , 其中flatten会减少 <Option<Option<T>>Option<T> , 和 flat_map会像 map 一样工作, 但采用返回 Option 的方法/闭包并将其压平。

flat_map非常简单:

fn opt_flat_map< T, U, F: FnOnce(T) -> Option<U> >(opt: Option<T>, f: F) -> Option<U> {
  match opt {
    Some(x) => f(x),
    None => None
  }
}

flatten更复杂,我真的不知道如何去定义它。它可能看起来像:

fn opt_flatten<T, U>(opt: Option<T>) -> Option<U> {
  match opt {
      Some( Some(x) ) => flatten_option( Some(x) ),
      _ => opt
  }
}

但这肯定行不通。有什么想法吗?

此外,我将如何在 Option 上实现这些方法?枚举,以便我可以在 Option 上本地使用它们实例?我知道我需要在 impl OptionExts for Option<T> 附近的某处添加类型签名,但我不知所措......

希望这是有道理的,我为我不精确的术语道歉——我是 Rust 的新手。

最佳答案

这些可能已经存在,只是名称与您期望的不同。检查docs for Option .

您将更正常地看到 flat_map 作为 and_then:

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

做你想做的更大的方法是用你想要的方法声明一个trait,然后为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);
}

对于flatten,我可能会这样写:

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);
}

但是如果你想要一个特质:

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

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

关于rust - 如何在 Option 上实现一些方便的方法(例如 flat_map、flatten)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28566531/

相关文章:

loops - 循环日期范围

linux - Rust 中的 Unix errno 常量在哪里?

rust - 调用从 map 方法返回Result <_,_>的函数

pointers - Rust 中的指针转换是否与 C++ 中的 reinterpret_cast 具有相同的行为?

rust - 输入符号名称和编号 : &5i

rust - 从 if 语句中返回值时出现 "mismatched types"错误

rust - 如何提取actix_web示例代码中的变量?

arrays - 如何在 Rust 中执行高效的向量初始化?

rust - 在编译时使用 serde_json 反序列化文件

reference - 如何创建带有引用向量的结构?