Ich habe mit Rust von porting my Score4 AI engine bis es gespielt - basierend auf meiner funktionalen Umsetzung in OCaml. Ich wollte speziell sehen, wie Rust mit funktionalem Code arbeitet.Warum benötigt das Argument für den Fundabschluss zwei kaufmännische Und-Zeichen?
Das Endergebnis: Es funktioniert, und es ist sehr schnell - viel schneller als OCaml. Es berührt fast die Geschwindigkeit von imperativem C/C++ - was wirklich cool ist.
Es gibt eine Sache, die mich jedoch beunruhigt - warum brauche ich zwei kaufmännische Und-Zeichen in der letzten Zeile dieses Codes?
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) {
...
Ich habe sie hinzugefügt, weil die Compilerfehler mich dazu "geführt" haben; aber ich versuche zu verstehen, warum ... habe ich den Trick an anderer Stelle im Stack-Überlauf erwähnt zu „fragen“ die Compiler, mir zu sagen, welche Art etwas ist:
let moves_and_scores: Vec<_> = moves_and_boards
.iter()
.map(|&(column,board)| (column, score_board(&board)))
.collect();
let() = moves_and_scores;
..., die diesen Fehler verursacht:
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;
... wie ich erwartet habe, moves_and_scores
ist ein Vektor von Tupeln: Vec<(u32, i32)>
. Aber dann, in der unmittelbaren nächsten Zeile, iter()
und find()
mich zwingen, die abscheulichen Doppel Et-Zeichen im Verschluß Parameter zu verwenden:
if let Some(killer_move) = moves_and_scores.iter()
.find(|& &(_,score)| score==target_score) {
Warum die find
Schließung müssen zwei Et-Zeichen? Ich konnte sehen, warum es einen brauchen könnte (das Tupel als Referenz übergeben, um Zeit/Raum zu sparen), aber warum zwei? Ist es wegen der iter
? Das heißt, ist das iter
Erstellen von Referenzen, und dann erwartet find
eine Referenz für jeden Eingang, so dass eine Referenz auf eine Referenz?
Wenn das so ist, ist das wohl kein recht hässlicher Designfehler in Rust?
In der Tat würde ich find
und map
und alle anderen funktionalen Primitiven als Teile der Sammlungen selbst erwarten. Zwingt mich zu iter()
, um jede Art von funktioneller Arbeit zu tun scheint lästig, und noch mehr, wenn es diese Art von "Doppel-Ampersands" in jeder möglichen funktionalen Kette zwingt.
Ich hoffe, dass ich etwas offensichtliches vermisse - jede Hilfe/Aufklärung willkommen.
Herzlichen Glückwunsch zum Verwalten des Ports, schlagen OCaml auf funktionalen Stil Code bedeutet, dass Sie etwas richtig gemacht haben! –
@MatthieuM. Vielen Dank! Ich hatte gehofft, es gibt eine sauberere Art, mit den Funktionsketten umzugehen (zB '.iter(). Map (...). Iter(). Filter() ... .iter(). Find (...)') ohne bei jedem Schritt eine zusätzliche Bezugsebene einzuführen - aber es scheint, ich kann es nicht vermeiden. – ttsiodras