选择第一个 Some() 选项的惯用方法?

Idiomatic way to choose the first Some() Option?

如果我有多个 Option<T>,并且我想选择第一个 Some 而不是 None - 是否有惯用的方法来做到这一点?

我的幼稚做法:

pub fn pick_first_option_available<T>(a: Option<T>, b: Option<T>, c: Option<T>) -> Option<T> {
    match a {
        Some(a) => Some(a),
        None => match b {
            Some(b) => Some(b),
            None => match c {
                Some(c) => Some(c),
                None => None,
            },
        },
    }
}

上面的一个明显问题是它仅限于固定数量的选项 (3)。我希望有一个更通用的功能。

有一个有点相关的线程 ,但它处理求和而不是选择选项。

作为@DenysSeguret 的回答,您甚至可以将其抽象为通用数量的选项:

use std::array;


pub fn pick_first_option_available<T, const N: usize>(options: [Option<T>; N]) -> Option<T> {
    array::IntoIter::new(options).reduce(Option::or).flatten()
}

Playground

此外,看起来 不受欢迎 但除了使用简单循环 Option::or 之外,仍然是一种方法:

use std::array;

pub fn pick_first_option_available<T>(a: Option<T>, b: Option<T>, c: Option<T>) -> Option<T> {
    for option in array::IntoIter::new([a, b, c]){
        if option.is_some() {
            return option;
        }
    }
    None
}

Playground

是的,有一个简单而惯用的方法:

a.or(b).or(c)

您通常不会为此定义一个函数。

Option#or