gpt4 book ai didi

rust - 我可以编写一个迭代器来改变自身然后产生对自身的引用吗?

转载 作者:行者123 更新时间:2023-11-29 08:33:09 25 4
gpt4 key购买 nike

我遇到了一个简化为以下问题的问题:

struct MyIter {
vec: Vec<i8>,
}

fn fill_with_useful_data(v: &mut Vec<i8>) {
/* ... */
}

impl<'a> Iterator for MyIter {
type Item = &'a [i8];

fn next(&mut self) -> Option<&'a [i8]> {
fill_with_useful_data(&mut self.vec);

Some(&self.vec)
}
}

fn main() {
for slice in (MyIter { vec: Vec::new() }) {
println!("{}", slice);
}
}

这会产生错误:

error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
--> src/main.rs:9:6
|
9 | impl<'a> Iterator for MyIter {
| ^^ unconstrained lifetime parameter

这个想法是迭代器做了一堆反射(reflect)在其字段中的工作,并且在每一步中,它都会产生对调用代码的自身引用。在这种情况下,我可以将其建模为生成状态的副本而不是引用,但让我们假装这是不可能的,或者只是非常昂贵。

直觉上这应该不是问题,因为借用检查器可以确保 .next() 不会被再次调用,而产生的引用仍然可以用于检查迭代器的状态,但是Iterator 特性似乎并没有直接提供那种东西。即使有一些排列,比如只在迭代器本身中保留对向量的引用,或者使迭代器成为一个引用,或者使生命周期更早地融入到类型中,我也无法通过借用检查器获得任何东西。

我阅读了“Iterators yielding mutable references”博文,但我不确定它是否/如何适用于我的不涉及可变引用的问题。

最佳答案

这是不可能的。如果允许,可以调用 next再次修改通过 & 可见的数据甚至完全使引用无效。这是因为 self 之间没有连接对象本身和返回的引用:没有明确的生命周期链接它们。

编译器对此进行推理并允许返回对 self 的引用接下来需要像这样的签名

fn next(&'a mut self) -> Option<&'a [i8]>

然而,这与特征的签名不同,后者不允许作为仅采用 T: Iterator<...> 的通用代码。不能说对某些T的返回值的使用有不同的要求;所有这些都必须以相同的方式处理。

Iterator trait 是为独立于迭代器对象的返回值而设计的,这对于像 .collect 这样的迭代器适配器是必需的。是正确和安全的。对于许多用途(例如 for 循环内的瞬时使用)来说,这比必要的限制更严格,但目前就是这样。我认为我们现在没有适当泛化此特征/for 循环的工具(具体来说,我认为我们需要具有更高等级生命周期的关联类型),但也许在未来。

关于rust - 我可以编写一个迭代器来改变自身然后产生对自身的引用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44658098/

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