"cannot infer type for `_`" 在 Rust 中对 iter 使用 map 时
"cannot infer type for `_`" when using map on iter in Rust
我遇到一个问题,我试图用随机 true/false 值初始化一个二维布尔数组,但编译器似乎无法推断出我需要的类型;我只是想知道我需要为推理引擎指定什么才能解决这个问题。
extern crate rand;
fn main() {
let mut grid = [[false; 10]; 10];
grid.iter_mut().map(|row| { [false; 10].iter().map(|_| { rand::random() }).collect() });
}
游乐场link(没有rand::random()
)
我得到的错误是
| grid.iter_mut().map(|row| { [false; 10].iter().map(|_| { rand::random() }).collect() });
| ^^^ cannot infer type for `_`
由于类型 [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);
}
注意在 collect 之后使用 "turbofish" 运算符 ::<>
来指定要收集到的类型,在本例中为 ::<[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
从现有对象生成一个 new 对象——它不映射 "in-place"。如果您真的想就地映射,您可以可以使用以下内容:
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]
好多了。当然,在这种特殊情况下,我的第一个例子可能就是要走的路。
我遇到一个问题,我试图用随机 true/false 值初始化一个二维布尔数组,但编译器似乎无法推断出我需要的类型;我只是想知道我需要为推理引擎指定什么才能解决这个问题。
extern crate rand;
fn main() {
let mut grid = [[false; 10]; 10];
grid.iter_mut().map(|row| { [false; 10].iter().map(|_| { rand::random() }).collect() });
}
游乐场link(没有rand::random()
)
我得到的错误是
| grid.iter_mut().map(|row| { [false; 10].iter().map(|_| { rand::random() }).collect() });
| ^^^ cannot infer type for `_`
由于类型 [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);
}
注意在 collect 之后使用 "turbofish" 运算符 ::<>
来指定要收集到的类型,在本例中为 ::<[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
从现有对象生成一个 new 对象——它不映射 "in-place"。如果您真的想就地映射,您可以可以使用以下内容:
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]
好多了。当然,在这种特殊情况下,我的第一个例子可能就是要走的路。