在 Rust 中,如何将“flatten”应用于 Option<Option<T>>?

10
我如何为“Option<U>”添加一个“flatten()”方法,该方法仅在“U”是“Option<T>”时才进行类型检查,或更简单地将其添加到“Option<Option<T>>”中?幼稚地说,我正在尝试编写以下内容,但无法编译:
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);
}
1个回答

10
由于内在一致性,您无法将内在实现(即您正在尝试的内容)写入未定义的类型中(如果可以,那么您怎么知道其他人没有定义了名为“flatten”的东西?)。
相反,您需要定义和实现一个具有所需方法的特质。您需要使用特质来使用该方法的任何位置。
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);
}

还要注意,我将方法的主题从&self更改为self:你不能移出借用物(特别是不可变的),所以在这里通过引用获取self并没有太多意义。


6
请注意,自 rust 1.40 起,Option<Option<T>> 类型有一个 flatten 函数。 - proc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接