です:
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);
}
「「ターボ魚 "オペレータ::<>
収集後に収集するタイプを指定します。この場合は::<[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
などです。だから我々は、例を変更することができます。だから何が与える
[false, false, false, false, false, false, false, false, false, false]
[true, false, false, true, true, false, true, false, true, true]
:
fn main() {
let mut arr = [false; 10];
let mapped = arr.iter_mut().map(|_| rand::random()).collect::<Vec<bool>>();
println!("{:?}", arr);
println!("{:?}", mapped);
}
しかし、これはあなたが望んでいた結果が得られない可能性がありますか?なぜ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);
}
しかし、イテレータのこの使用は、(混乱言及していない)unidiomatic考えられている
[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]
さらに優れています。もちろん、この特定のケースでは、私の最初の例は、おそらく行く方法です。
さて、['collect()'](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.collect)のドキュメントを読むことをお勧めします。クロージャーの戻り値の型が推論できない理由を理解すれば、まだサイズの配列に集めることができません。その後、あなたはそれに応じて質問を言い換えることができますか? –
パフォーマンスは別として、スレッドローカルRNGを何度も何度も掴む代わりに、 'Rng'をつかんで再利用したいと思うかもしれません。 – Shepmaster