【问题标题】:Match arms that return iterators?匹配返回迭代器的臂?
【发布时间】:2017-06-01 22:47:41
【问题描述】:

我有一些代码尝试运行每个分支可以返回不同类型的匹配,但是所有这些类型都实现了Iterator<Item=usize>

let found: Iterator<Item = usize> = match requirements {
    Requirements::A => MatchingAs { ainternals: [] },
    Requirements::B => MatchingBs { binternals: [] },
    Requirements::C => MatchingCs { cinternals: [] },
};

return found.any(|m| m == 1)

...其中MatchingAsMatchingBsMatchingCs 都是impl std::iter::Iterator&lt;Item = usize&gt;

Iterator 的大小不合适,我碰壁了:

    | the trait `std::marker::Sized` is not implemented for `std::iter::Iterator<Item=usize>`

有没有一种好的方法可以让匹配臂返回具有共享特征的对象,然后(仅)依赖于该特征来处理结果?

【问题讨论】:

标签: rust matching traits trait-objects


【解决方案1】:

当你想要返回不是Sized 的东西时,第一个反射是Box 它(也就是把它放在堆上,返回一个指针):

let found: Box<Iterator<Item = usize>> = match requirements {
    Requirements::A => Box::new(MatchingAs { ainternals: [] }),
    Requirements::B => Box::new(MatchingBs { binternals: [] }),
    Requirements::C => Box::new(MatchingCs { cinternals: [] }),
};

found.any(|m| m == 1)

这里还不够,因为现在match 会抱怨你返回不同的类型:Box&lt;MatchingAs&gt;Box&lt;MatchingBs&gt;,...

但是,只要有 impl Trait for ConcreteBox&lt;Concrete&gt; 就可以转换为 Box&lt;Trait&gt;,所以:

let found = match requirements {
    Requirements::A => Box::new(MatchingAs { ainternals: [] }) as Box<Iterator<Item = usize>>,
    Requirements::B => Box::new(MatchingBs { binternals: [] }) as Box<Iterator<Item = usize>>,
    Requirements::C => Box::new(MatchingCs { cinternals: [] }) as Box<Iterator<Item = usize>>,
};

found.any(|m| m == 1)

不过,有一个无需分配的解决方案:使用泛型。

fn search<T: Iterator<Item = usize>>(t: T) -> bool {
    t.any(|m| m == 1)
}

然后将该函数应用于match的每个分支:

match requirements {
    Requirements::A => search(MatchingAs {ainternals: []}),
    Requirements::B => search(MatchingBs {binternals: []}),
    Requirements::C => search(MatchingCs {cinternals: []}),
}

权衡是它有点接近回调地狱,有点间接流动。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多