gpt4 book ai didi

pointers - 当类型在结构定义中明确指定时,无法推断类型参数 T 的类型

转载 作者:行者123 更新时间:2023-12-03 11:23:57 27 4
gpt4 key购买 nike

我有一个结构定义,其中包括此字段:

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`

这个领域没有什么神秘之处。它的类型在结构定义中明确设置。我不明白为什么类型推断器不能推断出合适的类型来注入(inject)。

可以在下面和 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 对象由一堆迭代器组合器组成,包括像 MapTakeWhile 这样的组合器,它们的类型包括函数指针,因此是无名。
NonNull::dangling 不是参数函数: NonNull<T> 结构是参数的,但这个函数不是。因此,我不能只是想方设法摆脱困境。我完全不确定如何提供类型注释。

上下文,如果有用的话:我走这条路的全部原因是我试图创建一个迭代器组合器,为所有适当的迭代器自动实现,它在源迭代器的每个 N 元素之间注入(inject)一个元素。对于单个迭代器来说,实现它并不是那么难,但作为一个通用组合器更难实现,因为由 Itertools 的 IntoChunks 组合器生成的 chunks() 结构本身并不是一个迭代器,只是一个实现 IntoIterator 的结构。因此,我们需要跟踪 IntoChunks 结构以及它产生的迭代器。

我采用的方法是创建一个自引用结构 Separated ,其中包含这两者。假设结构总是固定的,这应该是安全的。然后我 impl Iterator for Separated 并将 next 调用推迟到 self.separated

最佳答案

根据标准文档, NonNull::dangling() 的定义这是:

impl<T> NonNull<T> {
pub const fn dangling() -> NonNull<T> {
/* ... */
}
}


在您的代码中,您在类型为 NonNull<dyn 'a + Iterator<Item = T>> 的表达式中使用它。 ,所以返回值必须是这个类型。

这里微妙的是泛型类型参数有一个隐含的 Sized绑定(bind)(除非它有 ?Sized 绑定(bind))。所以因为执行 NonNull::dangling没有 ?Sized绑定(bind),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`

    关于pointers - 当类型在结构定义中明确指定时,无法推断类型参数 T 的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60469553/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com