私は、によってRustと遊んでいます。これは、OCamlでの私の機能スタイルの実装に基づいています。私は、Rustが機能スタイルのコードでどのように運賃を払っているかを見たいと思っていました。Find Closureの引数に2つのアンパサンドが必要なのはなぜですか?
最終結果:これは動作し、非常に高速です。これはOCamlよりはるかに高速です。それは、命令型C/C++の速度にほとんど触れています。これは本当にクールです。
私には問題がありますが、このコードの最後の行に2つのアンパサンドが必要なのはなぜですか?
let moves_and_scores: Vec<_> = moves_and_boards
.iter()
.map(|&(column,board)| (column, score_board(&board)))
.collect();
let target_score = if maximize_or_minimize {
ORANGE_WINS
} else {
YELLOW_WINS
};
if let Some(killer_move) = moves_and_scores.iter()
.find(|& &(_,score)| score==target_score) {
...
私はそれらを追加したのは、コンパイラエラーが私にそれを「誘導」しているからです。しかし、私は理由を理解しようとしています...私は、コンパイラがどのようなタイプのものを私に伝えるために、「尋ねる」ためにスタックオーバーフローの他の場所で言及したトリックを使用:
:このエラーの原因let moves_and_scores: Vec<_> = moves_and_boards
.iter()
.map(|&(column,board)| (column, score_board(&board)))
.collect();
let() = moves_and_scores;
...
src/main.rs:108:9: 108:11 error: mismatched types:
expected `collections::vec::Vec<(u32, i32)>`,
found `()`
(expected struct `collections::vec::Vec`,
found()) [E0308]
src/main.rs:108 let() = moves_and_scores;
...期待どおり、moves_and_scores
はタプルのベクトルです:Vec<(u32, i32)>
です。しかし、その後、すぐに次の行に、iter()
とfind()
クロージャパラメータに恐ろしい重アンパサンドを使用するように私を強制:
if let Some(killer_move) = moves_and_scores.iter()
.find(|& &(_,score)| score==target_score) {
はなぜfind
閉鎖は2つのアンパサンドが必要なのですか?私はそれがなぜ必要なかもしれないのかを知ることができました(時間と空間を節約するために参照によってタプルを渡します)が、なぜ2つですか?それはiter
のためですか?つまり、は参照を作成し、次にfind
は各入力の参照を期待しているので、参照の参照は必要ですか?
これがそうであれば、間違いなく、Rustのかなり醜いデザインの欠陥ですか?
実際、find
とmap
と残りのすべての機能プリミティブは、コレクション自体の一部になると思います。私がiter()
に何らかの機能スタイルの作業を強制することは、すべての可能な機能チェーンでこのような「二重アンパサンド」を強制するとさらに負担になります。
私は何か明白であることを望んでいます - ご迷惑をおかけしておりません。
ポートを管理していただきありがとうございます。機能スタイルコードにOCamlを打つことは、あなたが正しいことをしたことを意味します! @MatthieuM。 –
ありがとう!私は機能的なチェーン(すなわち '.iter()。map(...)iter()。filter()... .iter()。find(...)')を処理するためのよりきれいな方法があることを期待していました。すべてのステップで追加のレベルの参照を導入することなく - しかし、私はそれを避けることはできないようだ。 – ttsiodras