如何在不使用Box的情况下从特征方法返回匿名类型?

时间:2018-04-23 12:14:33

标签: rust

我有一个扩展特征,其方法只是适配器/组合器的缩写:

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...)。
  • 存在类型可能会解决上述问题,但它们不会实施一段时间。

我也可以避免这个问题并使用宏或独立功能;不过,这也感觉不卫生。

更多见解?

1 个答案:

答案 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兼容的方式在内部使用非盒装选项重新实现它,这样做是可行的。