理解Rust中collect配合flat_map与map的行为差异
报错原因
你最初写法的核心问题是map返回的元素类型和你期望collect的目标类型不匹配:
grids_str.split("\r\n\r\n")会返回一个迭代器,迭代器的每一项是对应单个宾果表格的字符串切片&str- 你在
map的闭包中对每个表格字符串调用了split_whitespace(),这个方法返回的是SplitWhitespace类型的迭代器,而不是你想要的Vec<&str> - 此时
map处理完的整个迭代器的元素类型是SplitWhitespace<'_>,而你尝试用collect把它转为Vec<Vec<&str>>,Rust没有内置把SplitWhitespace迭代器直接转为Vec<&str>的实现,就会抛出你看到的FromIterator相关报错。
如果要得到你最初期望的嵌套向量Vec<Vec<&str>>,只需要在内层多加一次collect即可:
let bingo_sheet = grids_str .split("\r\n\r\n") .map(|grid| grid.split_whitespace().collect::<Vec<&str>>()) .collect::<Vec<Vec<&str>>>();
flat_map能运行的原因
flat_map和map的核心区别是它会自动展开闭包返回的迭代器:
- 你在
flat_map的闭包中返回的SplitWhitespace迭代器,会被flat_map自动遍历,把里面所有的&str元素直接抛到外层的大迭代器里 - 所有宾果表格的数字字符串会被拼接成一个一维的迭代器,最后
collect之后得到的是Vec<&str>类型的一维向量,注意这个结果并不是你最初想要的嵌套结构,只是刚好能编译通过而已。
内容的提问来源于stack exchange,提问作者gberth
相关产品推荐
相关产品推荐

