我遇到了一个问题,我试图初始化一个带有随机真/假值的二维布尔数组,但编译器似乎无法推断出我需要的类型;我只是想知道我需要为推理机指定什么才能解决这个问题.

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,但有许多可能的类型可以实现FromIterator,例如VecVecDequeHashSetBTreeSet等等.因此,我们可以修改示例:

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被宣布为可变的,但它没有发生Mutations ,而我们使用的是iter_mut?原因是map在现有对象的基础上生成了一个new对象——它没有"就地"映射.如果您真的想就地绘制 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]

好多了.当然,在这个特殊的情况下,我的第一个例子可能是要走的路.

Rust相关问答推荐

为什么Tauri要修改被调用函数的参数名称?

为什么幻影数据不能自动推断?

把Vector3变成Vector4的绝妙方法

trait声明中的生命周期参数

在Rust中,有没有一种方法让我定义两个 struct ,其中两个都遵循标准 struct ?

使用 struct 外部的属性来改变 struct 的原始方式

默认特征实现中的生命周期问题

使用Py03从Rust调用Python函数时的最佳返回类型

创建Rust中元对象协议的动态对象 Select /重新分配机制

无符号整数的Rust带符号差

为什么`AlternateScreen`在读取输入键时需要按Enter键?

Rust: 目标成员属于哪个"目标家族"的列表是否存在?

max(ctz(x), ctz(y)) 有更快的算法吗?

有什么方法可以通过使用生命周期来减轻嵌套生成器中的当生成器产生时borrow 可能仍在使用错误?

如何使返回 XMLError 的方法与 anyhow::Error 兼容?

预期类型参数,发现不透明类型

Rust,我如何正确释放堆分配的内存?

从函数返回 u32 的数组/切片

如何从 many0 传播 Nom 失败上下文?

为什么 u64::trailing_zeros() 在无分支工作时生成分支程序集?