【发布时间】:2020-02-29 20:57:25
【问题描述】:
我有一个结构定义,其中包括此字段:
pub struct Separated<'a, I, T>
{
..., // other fields,
separated: NonNull<dyn 'a + Iterator<Item = T>>,
}
不久之后,在其构造函数中,我尝试将该字段初始化为悬空指针:
let sep = Separated {
..., // other fields
separated: NonNull::dangling(),
};
奇怪的是,这会产生这个错误:
error[E0282]: type annotations needed
|
16 | separated: NonNull::dangling(),
| ^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
这个领域没有什么神秘之处;它的类型在结构定义中明确设置。我不明白为什么类型推断器不能推断出合适的类型来注入。
可以在下面找到产生此错误的最少 20 行示例和on the playground:
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> 结构是参数的,但这个函数不是。因此,我不能只是想方设法摆脱困境。我完全不确定如何提供类型注释。
上下文,如果有用的话:我走这条路的全部原因是我试图创建一个迭代器组合器,为所有适当的迭代器自动实现,它在源迭代器的每个 N 元素之间注入一个元素。对于单个迭代器来说实现起来并不难,但作为一个通用组合器就更难了,因为由 Itertools 的chunks() 组合器生成的IntoChunks 结构本身并不是一个迭代器,只是一个实现IntoIterator 的结构。因此,我们需要跟踪IntoChunks 结构以及它产生的迭代器。
我采用的方法是创建一个自引用结构Separated,它包含这两者。假设结构总是固定的,这应该是安全的。然后我impl Iterator for Separated 并将next 调用推迟到self.separated。
【问题讨论】:
标签: pointers rust non-nullable