我有一个 struct 定义,其中包括以下字段:
pub struct Separated<'a, I, T>
{
..., // other fields,
separated: NonNull<dyn 'a + Iterator<Item = T>>,
}
不久之后,在其构造函数中,我try 将该字段初始化为悬空指针:
let sep = Separated {
..., // other fields
separated: NonNull::dangling(),
};
奇怪的是,这会产生这样的错误:
error[E0282]: type annotations needed
|
16 | separated: NonNull::dangling(),
| ^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
这个领域没有什么神秘之处;其类型在 struct 定义中显式设置.我不明白为什么类型推断器不能推断出一个合适的类型来注入那里.
下面和on the playground中可以找到产生此错误的最少20行示例:
use std::pin::Pin;
use std::ptr::NonNull;
pub struct Separated<'a, T> {
t: &'a T,
separated: NonNull<dyn 'a + Iterator<Item = T>>,
}
impl<'a, T> Separated<'a, T>
where
T: 'a + Copy + PartialEq,
{
fn new(t: &'a T) -> Pin<Box<Self>> {
let sep = Separated {
t,
separated: NonNull::dangling(),
};
unimplemented!()
}
}
我确实需要separated
作为指向一个trait对象的指针,而不是一个单形类型:它将包含的真正trait对象由一组迭代器组合器组成,包括Map
和TakeWhile
这样的迭代器组合器,它们的类型包括函数指针,因此是不可测量的.
NonNull::dangling
不是参数化函数:NonNull<T>
struct 是参数化的,但此函数不是.因此,我不能只是用鱼来摆脱这一切.我完全不知道该如何提供类型注释.
上下文,如果有用的话:我走这条路的全部原因是我试图创建一个迭代器组合器,为所有适当的迭代器自动实现,它在源迭代器的每N个元素之间注入一个元素.对于单个迭代器来说,这并不是很难实现,但作为一个通用的组合器要困难得多,因为Itertools的chunks()
combinator生成的IntoChunks
struct 本身并不是一个迭代器,只是一个实现IntoIterator
的 struct .因此,我们需要跟踪IntoChunks
struct 及其生成的迭代器.
我采用的方法是创建一个自引用 struct Separated
,它包含这两个元素.假设 struct 始终处于固定状态,这应该是安全的.然后我拨打impl Iterator for Separated
,把next
个电话推迟到self.separated
个.