簡體   English   中英

在Rust中使用map時,“無法推斷出`_`”的類型

[英]“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 - 但是有許多可能的類型,例如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變異,即使它被宣布為可變,我們使用了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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM