Ich versuche Rust zu lernen, aber das einzige, was ich tue, ist, immer wieder gegen die Wand zu schlagen, um mir vertraute (mir) Java-Konzepte in sein Typsystem zu schaufeln. Oder versuchen, Haskell Konzepte, etc. zu schüren.Wie wird der gemeinsame veränderbare Zustand dargestellt?
Ich möchte ein Spiel mit einem Player
und viele Resource
s schreiben. Jeder Resource
kann von einem Player
besessen werden:
struct Player {
points: i32,
}
struct Resource<'a> {
owner: Option<&'a Player>,
}
fn main() {
let mut player = Player { points: 0 };
let mut resources = Vec::new();
resources.push(Resource {
owner: Some(&player),
});
player.points = 30;
}
Es ist nicht zu kompilieren, weil ich nicht die Ressource Punkt Spieler haben kann, während es gleichzeitig ändern:
error[E0506]: cannot assign to `player.points` because it is borrowed
--> src/main.rs:15:5
|
13 | owner: Some(&player),
| ------ borrow of `player.points` occurs here
14 | });
15 | player.points = 30;
| ^^^^^^^^^^^^^^^^^^ assignment to borrowed `player.points` occurs here
Außerdem , wenn die Resource
einen veränderlichen Verweis auf Player
besaß, konnte ich nicht sogar zwei Resource
s mit dem gleichen Inhaber haben.
Was ist der Weg von Rust, um solche Fälle zu lösen?
stark vereinfachte ich meine Frage, und während Shepmaster Antwort eine richtige Antwort darauf ist, es ist nicht das, was ich (weil das, was ich gefragt war nicht das, was ich wirklich fragen wollte) erhalten wollte. Ich werde versuchen, es umzuformulieren und mehr Kontext hinzuzufügen.
- Die Ressourcen sind in irgendeiner Weise verbunden - die Karte aller Ressourcen bildet einen (un) gerichteten Graphen.
- Jeder Spieler kann viele Ressourcen besitzen, jede Ressource kann einem Spieler gehören. Der Spieler sollte in der Lage sein, Punkte aus Ressourcen zu erhalten, die er besitzt. Ich dachte an eine Unterschrift wie:
fn addPoints(&mut self, allResources: &ResourcesMap) ->()
. - Der Spieler kann eine Ressource übernehmen, die mit einer seiner Ressourcen von einem anderen Spieler verbunden ist. Es könnte einige Punkteverlust für den anderen Spieler ergeben.
Probleme:
- Wie solche Graphen in Rust (eine möglicherweise cyclischer Struktur, wobei jeder Knoten aus zu vielen Knoten gerichtet werden kann) darstellen? Das ursprüngliche Problem: Wenn die
Resource
auf einePlayer
zeigt, kann ich den Player nicht ändern!
Resource
s Punkt zu Player
da - der natürliche Weg, eine solche Operation zu tun wäre, von einigen der Spieler A Ressourcen zu beginnen, eines Spielers B Ressource durch die Karte zu bewegen und von dieser Ressource zu Spieler B zu subtrahieren die Punkte. Es scheint in Rust einfach nicht natürlich zu sein (zumindest für mich).
Klingt gut. Meine Sorge ist, wenn ich versuche, Java-Code in Rust zu schreiben, kann es in einer Rust-Weise getan werden, ohne Kompilierungszeit-Sicherheit zu opfern? Vermeiden Sie diesen gemeinsamen veränderlichen Zustand überhaupt? –
Hinweis: Sie verzichten nicht auf Kompilierzeitsicherheit. Rust stellt sicher (zur Kompilierzeit), dass Sie Ihre Bibliotheken korrekt verwenden. Dennoch kann Ihr Programm zur Laufzeit in Panik geraten, wenn Sie die borrow * -Funktionen verwenden. Wenn Sie stattdessen die try_borrow * -Funktionen verwenden, können Sie überprüfen, ob dies erfolgreich war, und falls nicht, sollten Sie einen Fallback-Vorgang ausführen. –
Sie können auch eine Referenz-Box (http://doc.rust-lang.org/std/rc/index.html) zu einer RefCell zu Ihrem Typ verwenden. Dann müssen Sie nur sicherstellen, dass Sie keine Zyklen erstellen, oder Ihr Speicher wird nie freigegeben werden. Dies wäre viel mehr Java (obwohl Java automatisch Zyklen findet) –