Struct und mutable references in Rust

Gast #6345816
Lesenswert?
• ▲
▼
Ich probiere Rust aus und stecke in einem Problem und weiß nicht wie ich 
das elegant lösen soll. Mir ist klar dass es in Rust zum selben 
Zeitpunkt nur einen mutable Reference geben darf und es darf nicht 
gleichzeitig einen mutable und einen immutable Reference geben.

In diesem Beispiel steckt eine mutable reference in dem self Object der 
Objekt Methode add_neigbours. Es muss mutable sein damit ich die 
Funktion self.neighbours.push(i) aufrufen kann.

Und nun habe ich grundsätzlich ein Problem all_objects an die Methode 
add_neighbours zu übergeben. Der folgende Aufruf:
all_objects[i].add_neighbours(&all_objects);
erzeugt bereits beim Aufruf der Funktion add_neighbours eine mutable 
Reference für den self Parameter der Funktion. Dadurch kann ich 
all_objects weder als immutable noch als mutable Reference übergeben.

Beispielcode:
1
struct ObjectX {
2
    x: f64,
3
    y: f64,
4
    neighbours: Vec<usize>
5
}
6

7
impl ObjectX {
8
    fn add_neighbours(&mut self, all_objects: &Vec<ObjectX>) {
9
        for i in 0..all_objects.len() {
10
            let dis = ObjectX::dist(self.x, self.y, all_objects[i].x, all_objects[i].y);
11
            if dis < 120.0 {
12
                self.neighbours.push(i);
13
            }
14
        }
15
    }
16

17
    fn dist(x1: f64, y1: f64, x2: f64, y2: f64) -> f64 {
18
        let square_difference_x: f64 = (x2 - x1) * (x2 - x1);
19
        let square_difference_y: f64 = (y2 - y1) * (y2 - y1);
20
        let sum: f64 = square_difference_x + square_difference_y;
21
        sum.sqrt()
22
    }
23
}
24

25
fn main() {
26
    let mut all_objects = Vec::new();
27
    for _ in 0..100 {
28
        let obj = ObjectX { x: 1.0, y: 1.0, neighbours: Vec::new() };
29
        all_objects.push(obj);
30
    }
31

32
    for i in 0..all_objects.len() {
33
        all_objects[i].add_neighbours(&all_objects);
34
    }
35
}


Das führt zur folgenden Fehlermeldung:
1
error[E0502]: cannot borrow `all_objects` as immutable because it is also borrowed as mutable
2
  --> src/main.rs:33:39
3
   |
4
33 |         all_objects[i].add_neighbours(&all_objects);
5
   |         -----------    -------------- ^^^^^^^^^^^^ immutable borrow occurs here
6
   |         |              |
7
   |         |              mutable borrow later used by call
8
   |         mutable borrow occurs here
9

10
error: aborting due to previous error
Gast #6347236
Lesenswert?
• ▲
▼
Dieses Forum beschäftigt sich nunmal nicht mit Rust.
Ich selber muss es (unfreiwilligerweise) nutzen und
bin schon oft über diesen Checker gestolpert. Naja

Immerhin scheint hier das Problem beschrieben zu sein:
https://stackoverflow.com/questions/47618823/cannot-borrow-as-mutable-because-it-is-also-borrowed-as-immutable

Vielleicht hilft dir das. Rust meckert über jede
Kleinigkeit, in z.b. C++ wäre sowas trivial
Gast #6348094
Lesenswert?
• ▲
▼
Ok danke. Ich muss wohl sowieso nochmal in Ruhe die Rust Konzepte 
lernen.
Ich bin gerade ziemlich gefrustet und merke dass man mit herum probieren 
und Halbwissen nicht weit kommt. Wird erstmal nix mit der Idee durch die 
Praxis zu lernen. Variablen als mutable und Referenzen deklarieren zu 
können verkompliziert sehr schnell den ganzen Code und irgendwann weiß 
ich nicht mehr wirklich was ich tue.
Also wieder an die Theorie und sich zur Tode gähnen :D

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.