Teil 1: Heute lernen wir Rust

Ich habe vor ca. 1 Woche angefangen mich mit der Programmiersprache Rust zu beschäftigen. Als ich vor gut 1 Jahr wieder mit programmieren angefangen hatte, hatte ich die Sprachen Go und Rust in die engere Auswahl genommen. Letztendlich viel meine Entscheidung hier auf Go.

Der Grund warum ich nach gut einem Jahr jetzt doch noch einmal in Rust vorbeischaue ist reine Neugierde. Ich habe viel Gutes über die Sprache gehört und man wird dadurch ja auch nicht dümmer 😇.

Rust, Methoden und Ownership

Ich habe das Rust Buch gelesen (Klasse übrigens) und den Rustlings Kurs gemacht. Heute habe ich angefangen ein kleines Programm in Rust neu zu schreiben. Dabei habe ich ein paar Dinge über Ownership in Rust gelernt. Am besten verdeutlicht das glaube ich der Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
use std::string::String;

#[derive(Debug)]
struct Person {
    name: String,
    age: i32,
}

impl Person {
    fn hello(self) {
        println!("Hello {}, your age is {}", self.name, self.age);
    }
}

fn main() {
    let bob = Person {
        name: String::from("Bob"),
        age: 32,
    };
    bob.hello();
    println!("{:?}", bob)
}

Das sieht auf den ersten Blick richtig aus. Lässt man das Programm laufen bekommt man allerdings einen Fehler gezeigt:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
error[E0382]: borrow of moved value: `bob`
  --> src/main.rs:21:22
   |
16 |     let bob = Person {
   |         --- move occurs because `bob` has type `Person`, which does not implement the `Copy` trait
...
20 |     bob.hello();
   |         ------- `bob` moved due to this method call
21 |     println!("{:?}", bob)
   |                      ^^^ value borrowed here after move
   |
note: this function consumes the receiver `self` by taking ownership of it, which moves `bob`
  --> src/main.rs:10:14
   |
10 |     fn hello(self) {
   |   
     ^^^^

In Go würde man die Person einmal initialisieren und könnte dann beliebig oft die Methoden verwenden. Go würde hier lediglich zwischen einem Pointer und Nicht-Pointer Receiver unterscheiden, aber die Funktion wäre trotzdem immer verwendbar.

In Rust verbraucht die Verwendung der Methode das Objekt, da Sie durch die Verwendung self Eigentümer des Objektes ist.

Da ich die Person nach Verwendung der Methode gerne noch nutzen möchte, muss ich diese an die Methode verleihen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10

// ...

impl Person {
    fn hello(&self) {
        println!("Hello" {}, your age is {}", self.name, self.age");
    }
}

//...

Und schon funktioniert alles. Nach Beendigung des Codeblocks in der hello Methode wird self wieder zurückgegeben.

Ich werde wahrscheinlich ein wenig brauchen bis ich mich daran gewöhnt habe und auch noch das eine oder andere Mal darüber stopern.

0%