gpt4 book ai didi

iterator - 如何获取引用的 IntoIterator 并返回对修改值的引用的盒装迭代器?

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

我已经掌握了 Rust 生命周期的基础知识以及如何在其中使用迭代器,但仍然难以定义一个函数,该函数接受一个可迭代的元组并返回一个也在堆上分配的可迭代的元组。

(我知道“可迭代”在 Rust 中没有任何意义,但我仍然会使用它而不是 IntoInterator)

use std::iter::{once, repeat};

fn foo<'a, I>(costs: I) -> Box<Iterator<Item = &'a (i32, f32)>>
where
I: IntoIterator<Item = &'a (usize, f32)>,
{
let preliminary_examination_costs = once(10.0).chain(repeat(20.0));
let id_assignment_costs = once(10.0).chain(repeat(20.0));
let batch_fixed = once(10.0).chain(repeat(0.0));
let temp: Vec<(usize, &(i32, f32))> = costs.into_iter().enumerate().collect();
temp.sort_by_key(|&(_, &(n, cost))| n);
Box::new(temp.into_iter().map(|(i, &(n, cost))| {
(
i,
cost + preliminary_examination_costs.next().unwrap()
+ id_assignment_costs.next().unwrap() + batch_fixed.next().unwrap(),
)
}))
}

( playground )

这里是错误:

error[E0277]: the trait bound `std::vec::Vec<(usize, &(i32, f32))>: std::iter::FromIterator<(usize, &'a (usize, f32))>` is not satisfied
--> src/main.rs:10:73
|
10 | let temp: Vec<(usize, &(i32, f32))> = costs.into_iter().enumerate().collect();
| ^^^^^^^ a collection of type `std::vec::Vec<(usize, &(i32, f32))>` cannot be built from an iterator over elements of type `(usize, &'a (usize, f32))`
|
= help: the trait `std::iter::FromIterator<(usize, &'a (usize, f32))>` is not implemented for `std::vec::Vec<(usize, &(i32, f32))>`

error[E0271]: type mismatch resolving `<[closure@src/main.rs:12:35: 18:6 preliminary_examination_costs:_, id_assignment_costs:_, batch_fixed:_] as std::ops::FnOnce<((usize, &(i32, f32)),)>>::Output == &(i32, f32)`
--> src/main.rs:12:5
|
12 | / Box::new(temp.into_iter().map(|(i, &(n, cost))| {
13 | | (
14 | | i,
15 | | cost + preliminary_examination_costs.next().unwrap()
16 | | + id_assignment_costs.next().unwrap() + batch_fixed.next().unwrap(),
17 | | )
18 | | }))
| |_______^ expected tuple, found &(i32, f32)
|
= note: expected type `(usize, f32)`
found type `&(i32, f32)`
= note: required because of the requirements on the impl of `std::iter::Iterator` for `std::iter::Map<std::vec::IntoIter<(usize, &(i32, f32))>, [closure@src/main.rs:12:35: 18:6 preliminary_examination_costs:_, id_assignment_costs:_, batch_fixed:_]>`
= note: required for the cast to the object type `std::iter::Iterator<Item=&(i32, f32)>`

最佳答案

创建 MCVE 非常有用遇到问题时,这是我鼓励所有学习者去做的事情。这是一个镜像您的代码的 MCVE:

fn foo<'a, I>(costs: I) -> Box<Iterator<Item = &'a i32>>
where
I: IntoIterator<Item = &'a i32>,
{
Box::new(costs.into_iter().map(|i| i + 1))
}
error[E0271]: type mismatch resolving `<[closure@src/main.rs:5:36: 5:45] as std::ops::FnOnce<(&'a i32,)>>::Output == &i32`
--> src/main.rs:5:5
|
5 | Box::new(costs.into_iter().map(|i| i + 1))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected i32, found &i32
|
= note: expected type `i32`
found type `&i32`
= note: required because of the requirements on the impl of `std::iter::Iterator` for `std::iter::Map<<I as std::iter::IntoIterator>::IntoIter, [closure@src/main.rs:5:36: 5:45]>`
= note: required for the cast to the object type `std::iter::Iterator<Item=&i32>`

您正在接受一个引用,然后根据该引用创建一个全新的值。这意味着返回类型不再是引用,因此不支持您的函数签名。你需要改变它:

fn foo<'a, I>(costs: I) -> Box<Iterator<Item = i32>>

这将解锁另一个错误,因为编译器对 I::IntoIter 的具体类型了解不够:

error[E0310]: the associated type `<I as std::iter::IntoIterator>::IntoIter` may not live long enough
--> src/main.rs:6:5
|
6 | Box::new(costs.into_iter().map(|i| i + 1))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<I as std::iter::IntoIterator>::IntoIter: 'static`...
note: ...so that the type `std::iter::Map<<I as std::iter::IntoIterator>::IntoIter, [closure@src/main.rs:6:36: 6:45]>` will meet its required lifetime bounds
--> src/main.rs:6:5
|
6 | Box::new(costs.into_iter().map(|i| i + 1))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

我们按照它的建议进行并添加 'static 绑定(bind):

fn foo<'a, I>(costs: I) -> Box<Iterator<Item = i32>>
where
I: IntoIterator<Item = &'a i32>,
I::IntoIter: 'static,
{
Box::new(costs.into_iter().map(|i| i + 1))
}

另见:


error[E0277]: the trait bound `std::vec::Vec<(usize, &(i32, f32))>: std::iter::FromIterator<(usize, &'a (usize, f32))>` is not satisfied

这个错误是因为你有一个 (usize, &'a (usize, f32)) 的迭代器,你试图把它们变成 (usize, &(i32, f32 ))。您不能像这样转换类型。

关于iterator - 如何获取引用的 IntoIterator 并返回对修改值的引用的盒装迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47632097/

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