无法在for循环内使用链式方法
Unable to use chain method inside of for loop
据我了解,在迭代器上调用 chain 方法会消耗它和 returns 一种新类型。这是一个问题,因为我需要在一个 for 循环中将多个迭代器链接在一起。我的第一次尝试:
pub fn convert(s: String, num_rows: i32) -> String {
let mut iter = s.chars().enumerate().filter_map(|(i, c)| {
if i % ((num_rows as usize - 1)*2) == 0 {Some(c)} else {None}});
for n in 1..num_rows as usize {
iter = iter.chain(
s.chars().enumerate().filter_map(|(i,c)| {
let cycle = (num_rows as usize - 1)*2;
if i % cycle == n || i % cycle == cycle - n {Some(c)} else {None}
})
);
}
iter.collect()
}
这给了我一个错误:
error[E0308]: mismatched types
--> src/lib.rs:5:16
|
2 | let mut iter = s.chars().enumerate().filter_map(|(i, c)| {
| _____________________________________________________-
3 | | if i % ((num_rows as usize - 1)*2) == 0 {Some(c)} else {None}});
| | -
| | |
| |______________________________________________________________________the expected closure
| the found closure
4 | for n in 0..num_rows as usize {
5 | iter = iter.chain(
| ________________^
6 | | s.chars().enumerate().filter_map(|(i,c)| {
7 | | let cycle = (num_rows as usize - 1)*2;
8 | | if i % cycle == n || i % cycle == cycle - n {Some(c)} else {None}
9 | | })
10 | | );
| |_________^ expected struct `FilterMap`, found struct `std::iter::Chain`
|
= note: expected struct `FilterMap<Enumerate<Chars<'_>>, _>`
found struct `std::iter::Chain<FilterMap<Enumerate<Chars<'_>>, _>, FilterMap<Enumerate<Chars<'_>>, [closure@src/lib.rs:6:46: 9:14]>>`
没什么大不了的,我想。我将让它推断循环内的类型,如下所示:
pub fn convert(s: String, num_rows: i32) -> String {
let mut iter;
for n in 0..num_rows as usize {
iter = iter.chain(
s.chars().enumerate().filter_map(|(i,c)| {
let cycle = (num_rows as usize - 1)*2;
if i % cycle == n || i % cycle == cycle - n {Some(c)} else {None}
})
);
}
iter.collect()
}
这给了我一个新的错误,说我需要声明一个类型:
error[E0282]: type annotations needed
--> src/lib.rs:4:16
|
2 | let mut iter;
| -------- consider giving `iter` a type
3 | for n in 0..num_rows as usize {
4 | iter = iter.chain(
| ^^^^ cannot infer type
|
= note: type must be known at this point
所以,之后我尝试添加来自早期编译器错误的类型注释:
use core::str::Chars;
use core::iter::*;
let mut iter: Chain<FilterMap<Enumerate<Chars<'_>>, _>, FilterMap<Enumerate<Chars<'_>>, _>>;
这看起来很丑,但还是不行:
error[E0308]: mismatched types
--> src/lib.rs:6:16
|
6 | iter = iter.chain(
| ________________^
7 | | s.chars().enumerate().filter_map(|(i,c)| {
8 | | let cycle = (num_rows as usize - 1)*2;
9 | | if i % cycle == n || i % cycle == cycle - n {Some(c)} else {None}
10 | | })
11 | | );
| |_________^ expected struct `std::iter::FilterMap`, found struct `std::iter::Chain`
|
= note: expected struct `std::iter::Chain<std::iter::FilterMap<std::iter::Enumerate<Chars<'_>>, _>, std::iter::FilterMap<std::iter::Enumerate<Chars<'_>>, _>>`
found struct `std::iter::Chain<std::iter::Chain<std::iter::FilterMap<std::iter::Enumerate<Chars<'_>>, _>, std::iter::FilterMap<std::iter::Enumerate<Chars<'_>>, _>>, std::iter::FilterMap<std::iter::Enumerate<Chars<'_>>, [closure@src/lib.rs:7:46: 10:14]>>`
那么,我错过了什么?这怎么行?
您不能直接这样做,因为每次循环迭代都需要不同的类型:第一次 Chain<FilterMap, FilterMap>
,第二次 Chain<Chain<FilterMap, FilterMap>, FilterMap>
,然后 Chain<Chain<Chain<FilterMap, FilterMap>, FilterMap>, FilterMap>
第三次,以此类推。
这个问题可以通过装箱迭代器来解决:
pub fn convert(s: String, num_rows: i32) -> String {
let mut iter: Box<dyn Iterator<Item=char>> = Box::new (s.chars().enumerate().filter_map(|(i, c)| {
if i % ((num_rows as usize - 1)*2) == 0 {Some(c)} else {None}}));
for n in 1..num_rows as usize {
iter = Box::new(iter.chain(
s.chars().enumerate().filter_map(|(i,c)| {
let cycle = (num_rows as usize - 1)*2;
if i % cycle == n || i % cycle == cycle - n {Some(c)} else {None}
}))
);
}
iter.collect()
}
这给了你关于 n
被闭包借用的生命周期错误,通过添加 move
:
很容易修复
pub fn convert(s: String, num_rows: i32) -> String {
let mut iter: Box<dyn Iterator<Item=char>> = Box::new (s.chars().enumerate().filter_map(|(i, c)| {
if i % ((num_rows as usize - 1)*2) == 0 {Some(c)} else {None}}));
for n in 1..num_rows as usize {
iter = Box::new(iter.chain(
s.chars().enumerate().filter_map(move |(i,c)| {
let cycle = (num_rows as usize - 1)*2;
if i % cycle == n || i % cycle == cycle - n {Some(c)} else {None}
}))
);
}
iter.collect()
}
据我了解,在迭代器上调用 chain 方法会消耗它和 returns 一种新类型。这是一个问题,因为我需要在一个 for 循环中将多个迭代器链接在一起。我的第一次尝试:
pub fn convert(s: String, num_rows: i32) -> String {
let mut iter = s.chars().enumerate().filter_map(|(i, c)| {
if i % ((num_rows as usize - 1)*2) == 0 {Some(c)} else {None}});
for n in 1..num_rows as usize {
iter = iter.chain(
s.chars().enumerate().filter_map(|(i,c)| {
let cycle = (num_rows as usize - 1)*2;
if i % cycle == n || i % cycle == cycle - n {Some(c)} else {None}
})
);
}
iter.collect()
}
这给了我一个错误:
error[E0308]: mismatched types
--> src/lib.rs:5:16
|
2 | let mut iter = s.chars().enumerate().filter_map(|(i, c)| {
| _____________________________________________________-
3 | | if i % ((num_rows as usize - 1)*2) == 0 {Some(c)} else {None}});
| | -
| | |
| |______________________________________________________________________the expected closure
| the found closure
4 | for n in 0..num_rows as usize {
5 | iter = iter.chain(
| ________________^
6 | | s.chars().enumerate().filter_map(|(i,c)| {
7 | | let cycle = (num_rows as usize - 1)*2;
8 | | if i % cycle == n || i % cycle == cycle - n {Some(c)} else {None}
9 | | })
10 | | );
| |_________^ expected struct `FilterMap`, found struct `std::iter::Chain`
|
= note: expected struct `FilterMap<Enumerate<Chars<'_>>, _>`
found struct `std::iter::Chain<FilterMap<Enumerate<Chars<'_>>, _>, FilterMap<Enumerate<Chars<'_>>, [closure@src/lib.rs:6:46: 9:14]>>`
没什么大不了的,我想。我将让它推断循环内的类型,如下所示:
pub fn convert(s: String, num_rows: i32) -> String {
let mut iter;
for n in 0..num_rows as usize {
iter = iter.chain(
s.chars().enumerate().filter_map(|(i,c)| {
let cycle = (num_rows as usize - 1)*2;
if i % cycle == n || i % cycle == cycle - n {Some(c)} else {None}
})
);
}
iter.collect()
}
这给了我一个新的错误,说我需要声明一个类型:
error[E0282]: type annotations needed
--> src/lib.rs:4:16
|
2 | let mut iter;
| -------- consider giving `iter` a type
3 | for n in 0..num_rows as usize {
4 | iter = iter.chain(
| ^^^^ cannot infer type
|
= note: type must be known at this point
所以,之后我尝试添加来自早期编译器错误的类型注释:
use core::str::Chars;
use core::iter::*;
let mut iter: Chain<FilterMap<Enumerate<Chars<'_>>, _>, FilterMap<Enumerate<Chars<'_>>, _>>;
这看起来很丑,但还是不行:
error[E0308]: mismatched types
--> src/lib.rs:6:16
|
6 | iter = iter.chain(
| ________________^
7 | | s.chars().enumerate().filter_map(|(i,c)| {
8 | | let cycle = (num_rows as usize - 1)*2;
9 | | if i % cycle == n || i % cycle == cycle - n {Some(c)} else {None}
10 | | })
11 | | );
| |_________^ expected struct `std::iter::FilterMap`, found struct `std::iter::Chain`
|
= note: expected struct `std::iter::Chain<std::iter::FilterMap<std::iter::Enumerate<Chars<'_>>, _>, std::iter::FilterMap<std::iter::Enumerate<Chars<'_>>, _>>`
found struct `std::iter::Chain<std::iter::Chain<std::iter::FilterMap<std::iter::Enumerate<Chars<'_>>, _>, std::iter::FilterMap<std::iter::Enumerate<Chars<'_>>, _>>, std::iter::FilterMap<std::iter::Enumerate<Chars<'_>>, [closure@src/lib.rs:7:46: 10:14]>>`
那么,我错过了什么?这怎么行?
您不能直接这样做,因为每次循环迭代都需要不同的类型:第一次 Chain<FilterMap, FilterMap>
,第二次 Chain<Chain<FilterMap, FilterMap>, FilterMap>
,然后 Chain<Chain<Chain<FilterMap, FilterMap>, FilterMap>, FilterMap>
第三次,以此类推。
这个问题可以通过装箱迭代器来解决:
pub fn convert(s: String, num_rows: i32) -> String {
let mut iter: Box<dyn Iterator<Item=char>> = Box::new (s.chars().enumerate().filter_map(|(i, c)| {
if i % ((num_rows as usize - 1)*2) == 0 {Some(c)} else {None}}));
for n in 1..num_rows as usize {
iter = Box::new(iter.chain(
s.chars().enumerate().filter_map(|(i,c)| {
let cycle = (num_rows as usize - 1)*2;
if i % cycle == n || i % cycle == cycle - n {Some(c)} else {None}
}))
);
}
iter.collect()
}
这给了你关于 n
被闭包借用的生命周期错误,通过添加 move
:
pub fn convert(s: String, num_rows: i32) -> String {
let mut iter: Box<dyn Iterator<Item=char>> = Box::new (s.chars().enumerate().filter_map(|(i, c)| {
if i % ((num_rows as usize - 1)*2) == 0 {Some(c)} else {None}}));
for n in 1..num_rows as usize {
iter = Box::new(iter.chain(
s.chars().enumerate().filter_map(move |(i,c)| {
let cycle = (num_rows as usize - 1)*2;
if i % cycle == n || i % cycle == cycle - n {Some(c)} else {None}
}))
);
}
iter.collect()
}