[英]How to return an anonymous type from a trait method without using Box?
I have an extension trait whose methods are just shorthands for adapters/combinators: 我有一个扩展特征,其方法只是适配器/组合器的简写:
fn foo(self) -> ... { self.map(|i| i * 2).foo().bar() }
The return type of Trait::foo()
is some nested Map<Foo<Bar<Filter...
, including closures, and is therefor anonymous for all practical purposes. Trait::foo()
的返回类型是一些嵌套的Map<Foo<Bar<Filter...
,包括闭包,因此对于所有实际用途都是匿名的。 My problem is how to return such a type from a trait method, preferably without using Box
. 我的问题是如何从特征方法返回这样的类型,最好不使用Box
。
impl Trait
in return position would be the way to go, yet this feature is not implemented for trait methods yet. impl Trait
在返回位置将是要走的路,但是这个特性还没有为特征方法实现。 Box<Trait>
is possible, yet I don't want to allocate for every adapter shorthanded by the trait. 返回一个Box<Trait>
是可能的,但我不想为每个被特征缩短的适配器分配。 struct Foo<T> { inner: T }
can't be implemented (I promise an impl for all T
, yet only return a specific Foo<Map<Filter<Bar...
). 我不能将匿名类型放入结构中并返回它,因为struct Foo<T> { inner: T }
无法实现(我保证所有T
的impl,但只返回一个特定的Foo<Map<Filter<Bar...
)。 I could also just avoid the problem and use a macro or a freestanding function; 我也可以避免这个问题并使用宏或独立功能; this also feels unhygienic, though. 不过,这也感觉不卫生。
Any more insights? 更多见解?
What is the correct way to return an Iterator (or any other trait)? 返回迭代器(或任何其他特征)的正确方法是什么? covers all the present solutions. 涵盖所有现有的解决方案。 The one you haven't used is to replace closures with function pointers and then use a type alias (optionally wrapping in a newtype). 你没有使用的那个是用函数指针替换闭包然后使用类型别名(可选地换行换成新类型)。 This isn't always possible, but since you didn't provide a MCVE of your code, we can't tell if this will work for you or not: 这并不总是可行,但由于您没有提供代码的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() {}
Honestly, in these cases I would create a newtype wrapping the boxed trait object. 老实说,在这些情况下,我会创建一个包装盒装特征对象的新类型。 That way, I have the flexibility to internally re-implement it with a non-boxed option in an API-compatible fashion when it becomes practical to do so. 这样,我可以灵活地以API兼容的方式在内部重新实现它,当它变得切实可行时。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.