[英]“cannot infer type for `_`” when using map on iter in Rust
我有一個問題,我正在嘗試初始化具有隨機真/假值的布爾數組的二維數組,但編譯器似乎無法推斷我需要的類型; 我只是想知道我需要為推理引擎指定什么才能解決這個問題。
extern crate rand;
fn main() {
let mut grid = [[false; 10]; 10];
grid.iter_mut().map(|row| { [false; 10].iter().map(|_| { rand::random() }).collect() });
}
游樂場鏈接 (不含rand::random()
)
我得到的錯誤是
| grid.iter_mut().map(|row| { [false; 10].iter().map(|_| { rand::random() }).collect() });
| ^^^ cannot infer type for `_`
由於類型[T; 10]
[T; 10]
實施Rand
其中T: Rand
,可以使用rand::random()
直接:
extern crate rand;
fn main() {
let grid: [[bool; 10]; 10] = rand::random();
println!("{:#?}", grid);
}
至於為什么類型推斷在你的例子中失敗 - 這里有一些稍微簡單的東西來說明問題:
fn main() {
let mut arr = [false; 10];
let mapped = arr.iter_mut().map(|_| rand::random()).collect();
println!("{:?}", arr);
println!("{:?}", mapped);
}
給出錯誤:
error[E0282]: unable to infer enough type information about `_`
--> src/main.rs:5:13
|
5 | let mapped = arr.iter_mut().map(|_| rand::random()).collect();
| ^^^^^^ cannot infer type for `_`
|
= note: type annotations or generic parameter binding required
所以我們可以指定類型:
fn main() {
let mut arr = [false; 10];
let mapped = arr.iter_mut().map(|_| rand::random()).collect::<[bool; 10]>();
println!("{:?}", arr);
println!("{:?}", mapped);
}
注意在收集之后使用“turbofish”運算符::<>
來指定要收集的類型,在這種情況下::<[bool; 10]>
::<[bool; 10]>
。 不幸的是,編譯器會抱怨:
error[E0277]: the trait bound `[_; 10]: std::iter::FromIterator<bool>` is not satisfied
那么什么是std::iter::FromIterator<bool>
? 好吧,考慮一下collect
函數的定義:
fn collect<B>(self) -> B
where B: FromIterator<Self::Item>
這意味着您需要收集實現FromIterator<Self::Item>
任何類型。 遺憾的是,數組並不實現FromIterator
- 但是有許多可能的類型,例如Vec
, VecDeque
, HashSet
, BTreeSet
等。 所以我們可以修改這個例子:
fn main() {
let mut arr = [false; 10];
let mapped = arr.iter_mut().map(|_| rand::random()).collect::<Vec<bool>>();
println!("{:?}", arr);
println!("{:?}", mapped);
}
但是,這可能無法為您提供您希望的結果:
[false, false, false, false, false, false, false, false, false, false]
[true, false, false, true, true, false, true, false, true, true]
什么給出了什么? 為什么arr
變異,即使它被宣布為可變,我們使用了iter_mut
? 原因是map
從現有對象生成一個新對象 - 它不會“就地”映射。 如果您確實想要就地映射, 可以使用以下內容:
fn main() {
let mut arr = [false; 10];
let mapped = arr.iter_mut().map(|b| *b = rand::random()).collect::<Vec<()>>();
println!("{:?}", arr);
println!("{:?}", mapped);
}
生產
[true, false, true, true, true, false, false, false, true, true]
[(), (), (), (), (), (), (), (), (), ()]
但是,這種迭代器的使用被認為是單一的(更不用說令人困惑) - 慣用的方法是使用for
循環:
fn main() {
let mut arr = [false; 10];
for b in &mut arr {
*b = rand::random();
}
println!("{:?}", arr);
}
[false, true, true, true, false, false, true, false, true, false]
好多了。 當然在這種特殊情況下,我的第一個例子可能是要走的路。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.