我一直在玩Rust 移植我的Score4 AI引擎 它 - 基于我在OCaml中的功能样式实现的工作。我特别想看看Rust如何使用功能风格的代码。
最终结果:它的工作原理非常快 - 比OCaml快得多。它几乎触及了命令式C / C ++的速度 - 这真的很酷。
但是有一件事让我很烦恼 - 为什么我在这段代码的最后一行需要两个&符?
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) {
...
我添加它们是因为编译器错误“引导”了我;但我试图理解为什么......我使用Stack Overflow中其他地方提到的技巧来“询问”编译器告诉我什么类型的东西:
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()
强迫我在closure参数中使用hideous double&符号:
if let Some(killer_move) = moves_and_scores.iter()
.find(|& &(_,score)| score==target_score) {
为什么呢 find
关闭需要两个&符号?我可以看出为什么它可能需要一个(通过引用传递元组以节省时间/空间)但为什么两个?是因为 iter
?就是这样的 iter
创建引用,然后 find
期望每个输入的参考,所以参考参考?
如果是这样的话,可以说,这不是Rust中一个相当难看的设计缺陷吗?
事实上,我会期待 find
和 map
以及所有其他功能原语都是集合本身的一部分。强迫我 iter()
做任何类型的功能性工作似乎很麻烦,如果它在每个可能的功能链中强制使用这种“双符号”,那就更是如此。
我希望我遗漏了一些明显的东西 - 任何帮助/澄清都是最受欢迎的。