我有一个解析输入字符串的函数:
fn parse_input(s: &str) -> ((usize, usize), BTreeMap<(usize, usize), Tile>){
let mut start: (usize, usize) = (0,0);
let grid = s.split("\n").enumerate().flat_map(|(r,l)| {
l.chars().enumerate().map(move |(col, c)| {
let t = classify_tile(c);
match t {
Tile::Start => {
*start = (r, col);
((r,col), t)
},
_ => ((r,col), t)
}
})
}).collect::<BTreeMap<(usize, usize), Tile>>();
(start, grid)
}
我基本上想捕获起始图块的 r 和 col 值(这是唯一的,仅出现一次)。但目前,如果我尝试修改迭代器内的元组,我假设由于借用和范围原因,该值不会在迭代器外部修改。不过,迭代器完成很重要。
另一种解决方案是随后在 btreemap 中搜索起始图块,但我希望有一个更有效的解决方案。
我应该将其作为嵌套 for 循环吗?这里的迭代实际上是否更有效?
编辑:classify_tile 函数返回枚举类型。开始,土壤或管道。*start = (r,col) 部分不起作用。这是我试图解决这个问题的尝试。其他一切都可以。
如果您稍微重构一下迭代器,您就可以做您想做的事。
但我们首先要解决问题是什么。
作为一个更简单的例子,让我们计算所有大写字母(以一种愚蠢的方式):
如果我们尝试编译它,我们会遇到与您相同的问题:
这是为什么?
给定的闭包
map()
需要可变借用count
,这本身就很好。flat_map()
当我们加入其中时,问题就出现了。因为flat_map()
可能会产生多个迭代器。每个生成的迭代器都需要可变借用count
。这当然是不允许的,因为我们不能多次借用任何东西。总的来说,这个问题很容易解决,你只需重构迭代器:
或者
为你的迭代器解决这个问题,可能看起来像这样:
或者
它可以有多种写法。