Generics 如何展开任意数量的嵌套选项类型?

Generics 如何展开任意数量的嵌套选项类型?,generics,rust,Generics,Rust,我正在尝试编写一个特性,它允许我将多个嵌套的选项>“展开”为单个选项,以便更好地使用我正在使用的API。我正在尝试创建一个通用的解决方案,但我不知道如何使它工作 这是我的许多尝试之一: trait去凋亡{ fn展开选项(自)->选项; } 为选项执行取消配置{ fn展开选项(自)->选项{ 自己 } } 为选项执行取消配置{ fn展开选项(自)->选项{ 匹配自我{ 一些(e)=>e.展开, 无=>无, } } } fn main(){ 设x=Some(Some(Some(1)); printl

我正在尝试编写一个特性,它允许我将多个嵌套的
选项>
“展开”为单个
选项
,以便更好地使用我正在使用的API。我正在尝试创建一个通用的解决方案,但我不知道如何使它工作

这是我的许多尝试之一:

trait去凋亡{
fn展开选项(自)->选项;
}
为选项执行取消配置{
fn展开选项(自)->选项{
自己
}
}
为选项执行取消配置{
fn展开选项(自)->选项{
匹配自我{
一些(e)=>e.展开,
无=>无,
}
}
}
fn main(){
设x=Some(Some(Some(1));
println!(“{:?}”,x.unwrap_opt());
}
错误[E0282]:需要类型注释
-->src/main.rs:22:24
|
22 | println!(“{:?}”,x.展开_opt());
|                      --^^^^^^^^^^--
|                      | |
||无法推断在trait`unswoption'上声明的类型参数`T`的类型`
|此方法调用解析为`选项`

我用auto traits(
optin\u builtin\u traits
)解决了这个问题,但我不确定这是否是最好的方法:

#![feature(optin_builtin_traits)]

trait IsOption {}
impl<T> IsOption for Option<T> {}

auto trait IsSingleOption {}
impl<T> !IsSingleOption for Option<Option<T>> {}

trait UnwrapOption {
    type Inner;
    fn unwrap_opt(self) -> Option<Self::Inner>;
}

impl<T> UnwrapOption for Option<T>
where
    Self: IsSingleOption,
{
    type Inner = T;
    fn unwrap_opt(self) -> Option<Self::Inner> {
        self
    }
}

impl<T> UnwrapOption for Option<T>
where
    T: IsOption + UnwrapOption,
{
    type Inner = <T as UnwrapOption>::Inner;
    fn unwrap_opt(self) -> Option<Self::Inner> {
        match self {
            Some(e) => e.unwrap_opt(),
            None => None,
        }
    }
}

fn main() {
    let x = Some(Some(Some(1)));
    println!("{:?}", x.unwrap_opt());
    let x = Some(1);
    println!("{:?}", x.unwrap_opt());
}
#![功能(可选内置特性)]
性状等位基因{}
选项{}的impl IsOption
自动选项{}
恳求!选项{}的IsSingle选项
性状去凋亡{
型内;
fn展开选项(自)->选项;
}
为选项执行取消配置
哪里
赛尔夫:我有一个选择,
{
内型=T;
fn展开选项(自)->选项{
自己
}
}
为选项执行取消配置
哪里
T:等间距+无间距,
{
类型Inner=::Inner;
fn展开选项(自)->选项{
匹配自我{
一些(e)=>e.展开,
无=>无,
}
}
}
fn main(){
设x=Some(Some(Some(1));
println!(“{:?}”,x.unwrap_opt());
设x=Some(1);
println!(“{:?}”,x.unwrap_opt());
}

我建议不要将嵌套选项展平,而要将其展平,首先不要创建需要展平的
选项。在我所看到的大多数情况下,这是因为有人在本应使用选项::的时候误用了选项::地图
,然后:

fn main() {
    let input = user_input();

    let a = input.map(add1);
    // a is Option<Option<i32>>

    let b = input.and_then(add1);
    // a is Option<i32>
}

fn user_input() -> Option<i32> {
    Some(10)
}

fn add1(a: i32) -> Option<i32> {
    Some(a + 1)
}
fn main(){
让输入=用户输入();
设a=input.map(add1);
//一个是选择
设b=输入,然后(add1);
//一个是选择
}
fn用户输入()->选项{
一些(10)
}
fn add1(a:i32)->选项{
一些(a+1)
}
记住Rust是一种静态类型的语言;您将始终知道嵌套的确切级别

另见:


如果您有许多
选项
s,并且希望避免链接
展开
s,则可以使用
匹配

让val=Some(Some(Some)(Some(5));
让res=匹配val{
一些(一些(一些(v))=>v,
_=>0,//死机或默认
};

如果您知道有3次嵌套,为什么不直接调用
unwrap()
chained 3次呢
fn main(){let x=Some(Some(Some)(Some(1));println!(“{:?}”,x.unwrap().unwrap().unwrap());}
选项可能在某一点上不包含任何内容。例如:一些(无)或一些(一些(无))。这两个都不应该。我对生锈还不熟悉,但我明白你的意思。ThanksI建议不要将此命名为“unwrap”,因为这在Rust中通常意味着“没有恐慌”,而不是您试图在此处实施的行为。这实际上是我的问题-我没有意识到
,然后
是映射返回
选项的事物的正确方法