pointers - 当类型在结构定义中明确指定时,无法推断类型参数 T 的类型
问题描述
我有一个结构定义,其中包括此字段:
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 行示例:
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
and之类的TakeWhile
,其类型包括函数指针,因此无法命名。
NonNull::dangling
不是参数函数:NonNull<T>
结构是参数的,但这个函数不是。因此,我不能只是想方设法摆脱困境。我完全不确定如何提供类型注释。
上下文,如果有用的话:我走这条路的全部原因是我试图创建一个迭代器组合器,为所有适当的迭代器自动实现,它在源迭代器的每个 N 元素之间注入一个元素。对于单个迭代器来说,实现起来并不难,但作为一个通用组合器就更难了,因为IntoChunks
由 Itertools 的chunks()
组合器生成的结构本身并不是一个迭代器,只是一个实现IntoIterator
. 因此,我们需要跟踪IntoChunks
结构以及它产生的迭代器。
我正在采取的方法是创建一个自引用结构Separated
,它包含这两者。假设结构总是固定的,这应该是安全的。然后,我只是将电话impl Iterator for Separated
推迟到.next
self.separated
解决方案
根据标准文档,定义NonNull::dangling()
是这样的:
impl<T> NonNull<T> { pub const fn dangling() -> NonNull<T> { /* ... */ } }
在您的代码中,您在一个带有 type 的表达式的地方使用它NonNull<dyn 'a + Iterator<Item = T>>
,因此返回值必须具有这种类型。
这里微妙的是,泛型类型参数有一个隐式Sized
边界(除非它有一个?Sized
边界)。因此,由于 的实现NonNull::dangling
没有?Sized
界限,Rust 将尝试NonNull
根据这些要求推断 的类型参数:
- 因为该
NonNull::<T>::dangling()
方法没有绑定T: ?Sized
,所以只对有大小的类型实现T
,类型参数必须有大小。 - 类型参数必须是
dyn 'a + Iterator<Item = T>
.
然而,由于 trait 对象(“dyn Trait
类型”)没有大小,Rust 不可能同时满足这两个要求,因此它“无法推断类型参数的类型T
”。
事实上,通过将类型显式添加到您的 Playground 示例中,您将收到一条更明确地说明问题的不同错误消息:
let sep = Separated::<'a, T> {
t,
separated: NonNull::<dyn 'a + Iterator<Item = T>>::dangling(),
};
error[E0599]: no function or associated item named `dangling` found for type `std::ptr::NonNull<(dyn std::iter::Iterator<Item = T> + 'a)>` in the current scope
--> src/lib.rs:16:64
|
16 | separated: NonNull::<dyn 'a + Iterator<Item = T>>::dangling(),
| ^^^^^^^^ function or associated item not found in `std::ptr::NonNull<(dyn std::iter::Iterator<Item = T> + 'a)>`
|
= note: the method `dangling` exists but the following trait bounds were not satisfied:
`dyn std::iter::Iterator<Item = T> : std::marker::Sized`
推荐阅读
- latex - 乳胶文档中的页码未正确显示
- php - 未定义的属性:mysqli_stmt::$bind_param
- python - 将项目解释器目录链接到安装包的位置
- javascript - 在“Enter”键上发送数据 - React
- javascript - 如何修复中性白屏?
- sequelize.js - 是否可以在不循环的情况下在 Sequelize 中的传入值前面添加一些东西?
- android - 通知正文未出现在发布中
- java - 尝试执行 pentaho 作业时出错
- typescript - 打字稿:映射联合类型时的类型级数学
- python - 我做了一些解释其他代码的代码,但是无论我在那里写什么函数并尝试运行它,我都会得到一个 IndexError ...请帮助我