如何解决如何明确说明关联类型应该是什么?
我有一个类似于 Iterator
的特征,以及它的包装器:
pub struct Wrapped<I: Iterator>(I);
包装迭代器上的许多函数使用 impl-trait
返回新的包装迭代器。
impl <I: Iterator> Wrapped<I> {
pub fn foo(self) -> Wrapped<impl Iterator<Item=Foo<I::Item>>> {...}
pub fn bar(self) -> Wrapped<impl Iterator<Item=Bar<I::Item>>> {...}
}
这样一段时间后,用户很容易忘记调用代码中的迭代器项是什么(例如,对于像 my_wrapped.foo().bar().bar().foo()
这样的表达式)。
我想给用户一种方法来明确指定他们期望 Item
是什么类型,如果不是那种类型,那么就会出现编译时错误:
let y = x.foo().bar().bar().foo().assert_item_type::<Foo<Bar<Bar<Foo<X>>>>>()
但到目前为止,我发现这样做的唯一方法有点奇怪和丑陋。有没有更干净的方法?
pub trait Is {
type Myself;
}
impl<T> Is for T {
type Myself = T;
}
impl <I: Iterator> Wrapped<I> {
pub fn assert_item_type<Item: Is<Myself = I::Item>>(self) -> Self {
self
}
}
解决方法
如果你不介意使用一个独立的函数,你可以使用类似的方法而不需要任何特征:
fn assert_item_type<I: Iterator<Item=T>,T>(x: Wrapped<I>) -> Wrapped<I> {
x
}
let y = assert_item_type::<_,Foo<Bar<Bar<Foo<X>>>>>(x.foo().bar().bar().foo());
不幸的是,currently not possible 将 I
中的 assert_item_type
类型参数替换为 impl Iterator
(这将去掉 turbofish 中的下划线)作为编译器 { {3}} 在参数位置使用 impl Trait
时提供显式泛型参数。
如果在编译器中引入此功能,则该函数可以(假设)定义并用作:
fn assert_item_type<T>(x: Wrapped<impl Iterator<Item=T>>) -> Wrapped<impl Iterator<Item=T>> {
x
}
let y = assert_item_type::<Foo<Bar<Bar<Foo<X>>>>>(x.foo().bar().bar().foo());
,
这似乎不是 API 的目标。相反,用户不能在自己的代码中依靠典型的 impl trait 语法来完成这项任务吗?
例如
pip3 install boto3 --upgrade
虽然它不是用于此任务的专用方法,但它以更惯用的方式完成您的愿望。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。