In der Rust-Standardbibliothek gibt es mehrere Wrapper-Typen:
- Die Zellen im
std::cell
Modul :Cell
undRefCell
- Die referenzgezählten Wrapper wie
Rc
undArc
. - Die Typen im
std::sync
Modul :Mutex
oderAtomicBool
zum Beispiel
Nach meinem Verständnis sind dies Wrapper, die weitere Möglichkeiten bieten als eine einfache Referenz. Obwohl ich einige Grundlagen verstehe, kann ich nicht das ganze Bild sehen.
Was machen sie genau? Bieten Zellen und Familien mit Referenzzählung orthogonale oder ähnliche Merkmale?
Antworten:
In Rust gibt es zwei wesentliche Konzepte:
Die verschiedenen Zeigertypen (
Box
,Rc
,Arc
) mit betroffenen Eigentümer : Sie ermöglichen die Steuerung , ob ein einzelner oder mehr Eigentümer für ein einzelnes Objekt sind.Auf der anderen Seite sind die verschiedenen Zellen (
Cell
,RefCell
,Mutex
,RwLock
,AtomicXXX
) mit betroffenen Mutability .Die Grundregel für Rusts Sicherheit lautet Aliasing XOR Mutability . Das heißt, ein Objekt kann nur dann sicher mutiert werden, wenn kein herausragender Bezug zu seinem Inneren besteht.
Diese Regel wird im Allgemeinen beim Kompilieren vom Ausleihprüfer durchgesetzt :
&T
, können Sie nicht auch eine&mut T
für dasselbe Objekt im Gültigkeitsbereich haben.&mut T
, können Sie auch keinen Verweis auf dasselbe Objekt im Bereich haben.Manchmal ist dies jedoch nicht flexibel genug. Manchmal benötigen (oder möchten) Sie die Möglichkeit, mehrere Verweise auf dasselbe Objekt zu haben und es dennoch zu mutieren. Geben Sie die Zellen ein .
Die Idee von
Cell
undRefCell
ist es, die Veränderbarkeit bei Aliasing auf kontrollierte Weise zu ermöglichen :Cell
verhindert die Bildung von Verweisen auf sein Inneres, vermeidet baumelnde Verweise,RefCell
verschiebt die Durchsetzung von Aliasing XOR Mutability von der Kompilierungszeit zur Laufzeit.Diese Funktionalität wird manchmal als Bereitstellung innerer Veränderbarkeit beschrieben, dh , ein Objekt, das ansonsten von außen unveränderlich aussieht (
&T
), kann tatsächlich mutiert werden.Wenn diese Veränderlichkeit über mehrere Threads erstreckt, werden Sie stattdessen verwenden
Mutex
,RwLock
oderAtomicXXX
; Sie bieten die gleiche Funktionalität:AtomicXXX
sind nurCell
: kein Bezug zum Innenraum, nur Ein- / Ausziehen,RwLock
ist nurRefCell
: kann durch Wachen Hinweise auf das Innere erhalten ,Mutex
ist eine vereinfachte Version,RwLock
die nicht zwischen einem Nur-Lese-Schutz und einem Schreibschutz unterscheidet; so konzeptionell ähnlich wieRefCell
bei nur einerborrow_mut
Methode.Wenn Sie aus einem C ++ - Hintergrund stammen:
Box
istunique_ptr
,Arc
istshared_ptr
,Rc
ist eine nicht threadsichere Version vonshared_ptr
.Und die Zellen bieten eine ähnliche Funktionalität wie
mutable
, außer mit zusätzlichen Garantien, um Aliasing-Probleme zu vermeiden. Stellen Sie sichCell
alsstd::atomic
undRefCell
als nicht threadsichere Version von vorstd::shared_mutex
(die wirft, anstatt zu blockieren, wenn die Sperre aufgehoben wird).quelle
Dank der guten Antwort von Matthieu ist hier ein Diagramm, das den Menschen hilft, die Verpackung zu finden, die sie benötigen:
T
kann durch ersetzt werdenBox<T>
AtomicT
wennT
einebool
oder eine Zahl istUm zu wissen, ob Sie
Mutex
oder verwenden solltenRwLock
, lesen Sie diese verwandte Frage .quelle