Próbuję nauczyć się Rusta, ale jedyną rzeczą, którą robię, jest uderzanie w ścianę, próbując zsunąć znajome (dla mnie) koncepcje Javy do jej systemu typów. Lub spróbuj wymyślić koncepcje Haskella, itp.Jak reprezentować stan wspólnej zmienności?
Chcę napisać grę z Player
i wielu Resource
s. Każdy Resource
może być własnością jednej Player
:
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;
}
Nie skompilować, bo nie mogę mieć punkt zasobów do odtwarzacza, a jednocześnie modyfikując go:
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
Ponadto , jeśli Resource
ma zmienne odwołanie do Player
, nie mogę mieć dwóch Resource
s z tym samym właścicielem.
Jaki jest Rust sposób rozwiązania takich przypadków?
ja uproszczony moje pytanie, a jednocześnie odpowiedź Shepmaster jest poprawna odpowiedź na to, że nie jest to, co chciałem dostać (bo co prosiłem nie było to, co naprawdę chciałem zapytać). Spróbuję przeformułować to i dodać więcej kontekstu.
- Zasoby są połączone w jakiś sposób - mapa wszystkich zasobów tworzy (nie) skierowany wykres.
- Każdy gracz może posiadać wiele zasobów, każdy zasób może należeć do jednego gracza. Gracz powinien mieć możliwość zdobycia punktów z posiadanych przez siebie zasobów. Myślałem o podpisie:
fn addPoints(&mut self, allResources: &ResourcesMap) ->()
. - Gracz może przejąć zasób połączony z jednym ze swoich zasobów od innego gracza. Może to spowodować utratę punktów dla drugiego gracza.
Problemy:
- Jak do reprezentowania tych wykres w Rust (ewentualnie struktury cyklicznej, gdzie każdy węzeł może być skierowany do wielu węzłów)?
- Pierwotny problem: jeśli
Resource
wskazuje naPlayer
, nie mogę zmodyfikować odtwarzacza!
Resource
s punkt Player
ponieważ - naturalny sposób na takiej operacji byłoby zacząć od niektórych zasobów gracz A jest, poruszać się po mapie do B zasobu gracza i od tego zasobu do gracza B odjąć punkty. Po prostu nie wydaje się to naturalne w Rust (przynajmniej dla mnie).
Brzmi nieźle. Martwię się, jeśli to, co próbuję zrobić, to napisać kod Java w Rust, czy można to zrobić w sposób Rust, bez poświęcania czasu na kompilację? Unikaj w ogóle tego wspólnego, zmieniającego się stanu? –
Uwaga: nie poświęcasz czasu na kompilację. Rust upewnia się (podczas kompilacji), że poprawnie używasz swoich bibliotek. Mimo to twój program może panikować w czasie wykonywania, jeśli używasz funkcji pożyczania *. Jeśli zamiast tego użyjesz funkcji try_borrow *, możesz sprawdzić, czy udało się, a jeśli nie, wykonać operację zastępczą. –
Możesz również użyć pola licznika odwołań (http://doc.rust-lang.org/std/rc/index.html) do RefCell do swojego typu. Musisz tylko upewnić się, że nie tworzysz cykli, lub Twoja pamięć nigdy nie zostanie uwolniona. To byłoby o wiele bardziej podobne do java (chociaż java automatycznie znajduje cykle) –