我有一个扩展特征,其方法只是适配器/组合器的缩写:
fn foo(self) -> ... { self.map(|i| i * 2).foo().bar() }
Trait::foo()
的返回类型是一些嵌套的Map<Foo<Bar<Filter...
,包括闭包,因此对于所有实际用途都是匿名的。我的问题是如何从特征方法返回这样的类型,最好不使用Box
。
impl Trait
将是可行的方法,但尚未针对特征方法实现此功能。Box<Trait>
,但我不想为每个特征缺少的适配器进行分配。struct Foo<T> { inner: T }
无法实现(我保证所有T
的impl,但只返回一个具体Foo<Map<Filter<Bar...
)。我也可以避免这个问题并使用宏或独立功能;不过,这也感觉不卫生。
更多见解?
答案 0 :(得分:3)
What is the correct way to return an Iterator (or any other trait)?涵盖了目前所有的解决方案。您没有使用过的是用函数指针替换闭包,然后使用类型别名(可选择换行换成新类型)。这并不总是可行的,但由于您没有提供MCVE代码,我们无法判断这是否适合您:
use std::iter;
type Thing<T> = iter::Map<iter::Filter<T, fn(&i32) -> bool>, fn(i32) -> i32>;
trait IterExt: Iterator<Item = i32> {
fn thing(self) -> Thing<Self>
where
Self: Sized + 'static,
{
// self.filter(|&v| v > 10).map(|v| v * 2)
fn a(v: &i32) -> bool { *v > 10 }
fn b(v: i32) -> i32 { v * 2 }
self.filter(a as fn(&i32) -> bool).map(b as fn(i32) -> i32)
}
}
impl<I> IterExt for I
where
I: Iterator<Item = i32>,
{}
fn main() {}
老实说,在这些情况下,我会创建一个包装盒装特征对象的新类型。这样,我可以灵活地以API兼容的方式在内部使用非盒装选项重新实现它,这样做是可行的。