ProgrammierungRust-Entwickler / Backend-Entwickler

Was sind Konstruktoren und Fabrikmethoden in Rust (zum Beispiel new, with_capacity), wie implementiert man sie richtig und welche Fehler treten häufig bei Anfängern auf?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort.

Rust hat keine speziellen Konstruktoren wie zum Beispiel in C++/Java. Ein Konstruktor wird normalerweise als assoziierte Funktion implementiert (zum Beispiel new). Wichtige Eigenschaften:

  • Assoziierte Funktionen sind nicht mit Traits oder Objekten verknüpft, sie werden über :: aufgerufen.
  • Sie können sowohl self als auch Result<Self, E> zurückgeben — praktisch für fallible Konstruktoren.
  • Es können verschiedene Fabriken implementiert werden (with_capacity, from_str, benutzerdefinierte Varianten).

Beispiel für einen grundlegenden Konstruktor:

struct Point { x: i32, y: i32 } impl Point { pub fn new(x: i32, y: i32) -> Self { Point { x, y } } }

Beispiel für einen fallible Konstruktor:

impl Point { pub fn try_new(x: i32, y: i32) -> Result<Self, String> { if x < 0 || y < 0 { Err("Koordinaten müssen nicht negativ sein".to_string()) } else { Ok(Point { x, y }) } } }

Trickfrage.

Welcher Funktionstyp sollte für einen Konstruktor verwendet werden: normale Funktion, Methode oder assoziierte Funktion, und warum?

Viele antworten: "Methode". Aber in Rust sind Konstruktoren — nur assoziierte Funktionen (ohne self), da es noch kein Exemplar gibt und eine normale Methode nicht aufgerufen werden kann.

struct Foo; impl Foo { // assoziierte Funktion, keine Methode pub fn new() -> Self { Foo } }

Beispiele für echte Fehler aufgrund mangelnden Wissens über die Feinheiten des Themas.


Geschichte

Ein Programmierer implementierte den Konstruktor als Methode:

impl Point { pub fn make(&self, x: i32, y: i32) -> Self { ... } }

Das ist unlogisch und verwirrend: Um ein Objekt zu erstellen, benötigt man ein Objekt, das noch nicht existiert! Der Entwickler war unsicher, wie man diese Methode aufruft. Es wurde auf eine statische Funktion geändert.


Geschichte

Klassischer Fehler: Rückgabe von Option<Self> für einen fallible Konstruktor ohne Warnung, was dazu führte, dass Fehler kaskadiert übersehen wurden. Nachdem wir Result<Self, E> zurückgegeben hatten, wurde es möglich, Fehler deutlicher anzuzeigen.


Geschichte

Implementierung von Fabriken wie from_parts, from_str ohne Verwendung des Traits From/FromStr. Infolgedessen funktionierten die Standardkonvertierungsmechanismen nicht (zum Beispiel str.parse::<MyType>()). Nach Entdeckung des Fehlers haben wir FromStr implementiert und die Kompatibilität des Codes mit den Bibliotheken des Ökosystems verbessert.