我一直在使用 Rust 技术,将我基于 OCaml 实现的函数式 Score4 AI 引擎进行了移植。我特别想看看 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 其他地方提到的技巧,向编译器“询问”某个东西的类型。
我之所以添加它们,是因为编译器的错误信息“指引”我这样做;但是我正试图理解为什么……我使用了 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()
强制我在闭包参数中使用丑陋的双重引用符号:
if let Some(killer_move) = moves_and_scores.iter()
.find(|& &(_,score)| score==target_score) {
find
闭包为什么需要两个“&”?我可以理解为什么需要一个(通过引用传递元组来节省时间/空间),但是为什么需要两个呢?这是因为iter
吗?也就是说,iter
创建了引用,然后find
期望在每个输入上都有一个引用,因此需要一个引用的引用?如果是这样的话,这是否是Rust中相当丑陋的设计缺陷?
实际上,我希望
find
、map
和所有其他函数式基元都是集合本身的一部分。强制我使用iter()
来执行任何类型的函数式工作似乎很繁琐,如果它迫使我在每个可能的函数式链中都使用这种“双“&””,那么更是如此。我希望我错过了一些显而易见的东西-任何帮助/澄清都非常欢迎。
.iter().map(...)。iter().filter() ... .iter().find(...)
)而不需要在每个步骤中引入额外的引用级别 - 但似乎我无法避免它。 - ttsiodras