gpt4 book ai didi

rust - Rust:错误[E0495]:由于关闭中的冲突要求,无法推断出适当的生命周期以自动引用

转载 作者:行者123 更新时间:2023-12-03 11:37:53 25 4
gpt4 key购买 nike

原始想法

在一个虚拟项目中,我想使用循环迭代器(例如,生成整数)。

use std::iter::Cycle;

type IntegerCycle = Cycle<std::slice::Iter<'static, i32>>;

fn generate_cycles() -> [IntegerCycle; 2] {
let mut cycles = [
[1, 2].iter().cycle(),
[2, 4].iter().cycle(),
];

cycles
}


fn main() {
let mut cycles = generate_cycles();
// ...
}

重构

尽管上一段代码按预期工作,但我的实际示例更加复杂,因此我希望调整 generate_cycles函数以执行更多操作(在以下示例中,乘以2,然后生成循环迭代器)。
为此,我尝试使用 arraymap:

extern crate arraymap;

use arraymap::ArrayMap;
use std::iter::Cycle;

type IntegerCycle = Cycle<std::slice::Iter<'static, i32>>;

fn generate_cycles() -> [IntegerCycle; 2] {
let mut cycles = [
[1, 2],
[2, 4],
];

cycles
.map(|points| {
points.map(|point| point*2)
})
.map(|points| {
points.iter().cycle()
})
}


fn main() {
let mut cycles = generate_cycles();
// ...
}

问题

上面的解决方案不起作用,并且,由于Rust初学者最近接触到“生命周期”的概念,我不明白为什么编译器会在这里提示,或者我可以做些什么来使他感到高兴。
error[E0495]: cannot infer an appropriate lifetime for autorefdue to conflicting requirements
--> src/main.rs:20:14
|
20 | points.iter().cycle()
| ^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 19:10...
--> src/main.rs:19:10
|
19 | .map(|points| {
| __________^
20 | | points.iter().cycle()
21 | | })
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:20:7
|
20 | points.iter().cycle()
| ^^^^^^
= note: but, the lifetime must be valid for the static lifetime...
= note: ...so that the expression is assignable:
expected [std::iter::Cycle<std::slice::Iter<'static, i32>>; 2]
found [std::iter::Cycle<std::slice::Iter<'_, i32>>; 2]

这是一个REPL,其中的代码尝试利用 arraymap: https://repl.it/repls/ShadowyStrikingFirm

最佳答案

在您的类型声明中:

type IntegerCycle = Cycle<std::slice::Iter<'static, i32>>;

您说用于构建迭代器的基础切片必须具有 'static生存期,也就是说,它们必须永远存在。然后,您使用诸如 [1, 2]之类的文字数组作为所有文字,都具有 'static'生存期,并且一切顺利:
let r: &'static [i32; 2] = &[1, 2]; //Ok

但是,然后,您尝试使用类似于以下简单代码的代码:
let a = [1, 2].map(|x| 2 * x);
let r: &'static [i32; 2] = &a; //error: borrowed value does not live long enough

那是 arraymap::map的结果是一个普通数组,而不是文字数组,因此它没有 'static生存期。它不能是静态的,因为您正在运行时中计算值。只要变量 a,它就会根据需要生存。

在您的情况下,由于 arraymap::map的返回未分配给变量,因此它们是临时值并且会被快速删除。但是,即使将其分配给局部变量,也无法返回对其的引用,因为在函数结束时会删除局部变量。

解决方案是返回拥有该值的迭代器。像这样的作品:
type IntegerCycle = Cycle<std::vec::IntoIter<i32>>;

fn generate_cycles() -> [IntegerCycle; 2] {
let cycles = [
[1, 2],
[2, 4],
];
cycles
.map(|points| {
points.map(|point| point*2)
})
.map(|points| {
points.to_vec().into_iter().cycle()
})
}

不幸的是,您必须使用 Vec而不是数组,因为没有针对数组的 IntoIterator实现(存在切片,但它们不拥有值)。

如果要避免额外分配 Vec,可以使用确实允许将迭代器带到数组的 arrayvec crate :
type IntegerCycle = Cycle<arrayvec::IntoIter<[i32; 2]>>;

fn generate_cycles() -> [IntegerCycle; 2] {
let cycles = [
[1, 2],
[2, 4],
];

cycles
.map(|points| {
points.map(|point| point*2)
})
.map(|points| {
let a = arrayvec::ArrayVec::from(*points);
a.into_iter().cycle()
})
}

注意:似乎正在尝试将适当的 IntoIterator impl for arrays by value添加到 std,但是仍然存在一些 Unresolved 问题。

关于rust - Rust:错误[E0495]:由于关闭中的冲突要求,无法推断出适当的生命周期以自动引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60029939/

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