2016-02-22 12 views

Antwort

6

() ist einfach ein Tupel ohne Werte; ein 0-Tupel. Der Typ und der Wert sind gleich geschrieben, beide (). Der Typ wird manchmal als "Einheitstyp" bezeichnet. es war früher ein eigener Typ im Compiler, wird aber jetzt nur noch als entartetes Tupel behandelt. Es ist ein 0-Typ; Objekte dieses Typs nehmen niemals wirklich Platz ein, obwohl es ein Sized Typ ist, nur mit einer Größe von 0.

Es wird für Fälle verwendet, in denen Sie einen Wert oder einen Typ haben müssen, aber Sie haben nichts Relevantes dort zu setzen. Wenn Sie beispielsweise eine Funktion haben, die keinen Wert zurückgibt, und sie an einer Stelle aufruft, die einen Wert erwartet, erhalten Sie den Wert () vom Typ ().

fn nothing() {} 

fn main() { 
    println!("{:?}", nothing()); 
} 

das druckt () (playpen).

Eine andere Verwendung ist, wenn Sie einen generischen Typ wie Result<T, E> haben, der einen Erfolg oder einen Fehlschlag eines Vorgangs angibt und entweder das Ergebnis des erfolgreichen Vorgangs oder einen Fehler enthalten kann, der angibt, warum der Vorgang fehlgeschlagen ist. Einige Operationen, wie z. B. std::io::write, die keinen Rückgabewert haben, wenn sie erfolgreich sind, aber einen Fehler anzeigen möchten, geben eine std::io::Result zurück, die eigentlich ein Synonym für Result<(), std::io::Error> ist; Dadurch kann die Funktion im Erfolgsfall Ok(()) zurückgeben, aber bei einem Fehler wird ein bedeutungsvoller Fehler angezeigt.

Sie könnten es mit void in C oder C++ vergleichen, die auch für einen fehlenden Rückgabewert verwendet werden. Sie können jedoch niemals ein Objekt schreiben, das den Typ void hat, wodurch void in der generischen Programmierung viel weniger nützlich ist; Sie könnten nie einen gleichwertigen Result<void, Error> Typ haben, weil Sie niemals den Ok Fall konstruieren könnten.

In diesem Fall wird normalerweise ein Mutex Wraps und Objekt, die Sie zugreifen möchten; Sie können also dieses Objekt in den Mutex einfügen und dann auf den Wächter zugreifen, den Sie erhalten, wenn Sie den Mutex sperren.In diesem Beispiel werden jedoch keine aktuellen Daten geschützt, so dass () verwendet wird, da Sie etwas hineinlegen müssen, und Mutex ist generisch über den Typ, so dass es jeden Typ annehmen kann.

+0

Vielleicht fügen Sie den Begriff "void" hinzu? Die meisten Programmierer kennen "void", also würde es helfen, oder? –

+1

@LukasKalbertodt: Es gibt Kosten zu "void", obwohl es unregelmäßig ist. In der C++ Template-Programmierung ist zum Beispiel 'void' ein Albtraum. Auf der anderen Seite ist '()' perfekt in das Typsystem integriert => es ist nur ein Tupel wie jedes andere. –

+0

@MatthieuM. Richtig, aber ** ich ** denke immer noch, dass es Programmierern aus anderen Sprachen helfen würde, es mit "void" zu vergleichen ... –

8

() ist das leere tuple, auch unit type genannt - ein Tupel ohne Elementtypen. Es ist auch der einzige gültige Wert dieses Typs. Es hat a size of zero (beachten Sie, dass es immer noch Sized ist, nur mit einer Größe von 0), wodurch es zur Laufzeit nicht existent. Dies hat mehrere nützliche Effekte, von denen eine hier verwendet wird.

Hier wird () verwendet, um eine Mutex ohne eigene Daten zu erstellen - es ist nur ein freischaltbarer und abschließbarer Mutex. Wenn wir ausdrücklich auf die Art Inferenz mit dem ::<>turbofish operator schreiben, könnten wir auch schreiben:

Mutex::<()>::new(()) 

Das heißt, wir haben ein newMutex schaffen, die () eine () mit dem Anfangswert enthält.

+0

Ich fragte mich immer, wie diese Syntax hieß ... cool link. – squiguy

+0

Ja, es ist eines meiner Lieblingsdinge an Rust ... Ich versuche es überall hin zu streuen, damit es durchsuchbarer wird. – thirtythreeforty

+0

Kann auch hilfreich sein, um zu notieren, ob solche Größen wie "Größe" zählen oder nicht. (Sie tun, richtig?) – LinearZoetrope

Verwandte Themen