【发布时间】:2020-11-30 17:14:21
【问题描述】:
我正在尝试创建一个从字符串扩展迭代器并返回平面地图的特征,这是我目前得到的结果
trait WordsExt<'a, F>: Iterator<Item = &'a str>
where
Self: Sized,
F: FnMut(&'a str) -> Split<'a, &'a str>,
{
fn words(self) -> FlatMap<Self, Split<'a, &'a str>, F> {
self.flat_map(|x: &'a str| x.split(" "))
}
}
我被困在闭包类型上。
我也试过了
struct Words<'a, I>
where
I: Iterator<Item = &'a str>,
{
inner: I,
}
trait WordsExt<'a>: Iterator<Item = &'a str>
where
Self: Sized,
{
fn words(
self,
) -> Words<'a, FlatMap<Self, Split<'a, &'a str>, Fn(Self::Item) -> Split<'a, &'a str>>>
{
Words {
inner: self.flat_map(|x: &'a str| x.split(" ")),
}
}
}
我每次都遇到这个问题。我需要返回一个特征。当我在一个函数中时,我可以使用impl Trait 语法。但是当表达一个特质时,我无法表达这一点。据我所知,我能得到的更接近的是使用泛型,以便方法在调用时被单态化。但是我需要让用户选择具体的类型。在这种情况下,闭包是实现细节,它不应该泄露给用户。
我遇到了这个答案How can I add new methods to Iterator?
在这种情况下,OP 用例有一个内部状态。就我而言,我只想创建一个别名i.words() -> i.flat_map(|x| x.split(" "))
我知道连贯性,因此我可能需要在 Iterator 上创建一个包装器,因为 Iterator 不在我的 crate 下。这是第二次尝试。
我可以通过简单的方式实现一个函数
fn words<'a>(i: impl Iterator<Item = &'a str>) -> impl Iterator<Item = &'a str> {
i.flat_map(|x| x.split(" "))
}
但我无法用 trait 语法表达相同的意思,因为 trait 中没有 impl Trait 语法。所以......我有两个选择,动态调度和泛型,它们都不理想。更进一步。由于这些结构没有大小,我不能对其使用静态调度,所以我被困在简单的动态调度上
下面的结构无效
struct Words<'a>(Iterator<Item = &'a str>);
最后,我希望给定一个函数F(X),我总是能够重构它以编写一个X.F(),但这似乎不是真的,因为虽然我能够编写fn f(x) -> impl Y,但我是无法表达trait X { fn (self) -> impl Y },终于不再重复泛型或动态调度。
我试图用一种流畅的语法编写迭代器组合器:iterator.comb1().comb2().comb3()
【问题讨论】:
标签: rust