Rusts dyn Trait im Speicher: Visualisierung der Vtables
Visualizing Rust's Vtables: How dyn Trait Works In Memory

Dieser Artikel erklärt Rusts dynamische Dispatch mit `dyn Trait` anhand von Speichervisualisierungen. Die Autorin vergleicht Rusts Ansatz mit C++ (virtuelle Funktionen und CRTP) und zeigt, wie Rust statische Dispatch durch Monomorphisierung und dynamische Dispatch durch Vtables in fat pointers umsetzt. Sie entdeckt dabei überraschende Eigenheiten wie Zero-Sized Types und erklärt, warum `Vec<Box<dyn Draw>>` heterogene Typen erlaubt. Ein zentraler Unterschied: In Rust entscheidet der Aufrufort über statisch oder dynamisch, nicht die Klasse.
In Rust wird die Wahl zwischen statischer und dynamischer Dispatch am Aufrufort getroffen – `Circle` ist einfach `Circle` und weiß nichts über Dispatch.
- tialaramex
Dieser Artikel enthält einen Abschnitt über Object Safety. Ich habe nachgesehen und der Artikel wurde diese Woche geschrieben, aber "Object Safety" ist ein verwirrender Name für diese Idee, und deshalb nennt Rust diese Idee seit einiger Zeit "dyn compatibility", weil das Wichtigste, was man bekommt, wenn ein Trait "dyn kompatibel" ist, die Möglichkeit ist, "dyn Trait" zu verwenden – https://doc.rust-lang.org/1.98.1/reference/items/traits.html...
Dieser Link erklärt die Regeln auch umfassender.
[Edit: Mir ist aufgefallen, dass das Ende des Artikels dies erklärt; der Autor begann den Artikel vor Monaten zu schreiben, wahrscheinlich bevor er von der verbesserten Benennung "dyn compatibility" gelesen hat]
- Panzerschrek
> Ein Trait muss die sogenannten Object-Safety-Regeln erfüllen, um als Trait-Objekt verwendet zu werden.
Das scheint mir ein großer Designfehler von Rust zu sein. Es versucht, Traits für dynamische Polymorphie umzufunktionieren, auch wenn das nicht perfekt passt. C++ ist ehrlicher: Es hat zwei getrennte Mechanismen für statische Polymorphie (Templates) und dynamische Polymorphie (Vererbung).
- Panzerschrek
Ich hatte einmal einen kniffligen Bug mit fetten Zeigern (die virtuelle Tabellen enthalten) in Rust. Zwei solche Zeiger können verschieden sein, selbst wenn sie auf dasselbe Objekt verweisen, weil der Compiler (aus irgendeinem Grund) zwei (oder sogar mehr) Kopien der Tabelle der virtuellen Funktionen erzeugen und an verschiedenen Stellen verwenden kann.
- evmar
Auf meiner eigenen Entdeckungsreise fand ich https://cheats.rs/ sehr hilfreich, insbesondere der Abschnitt "memory layout" enthält Visualisierungen. (Keine Verbindung zur Website, nur ein zufriedener Leser!)
- returningfory2
Sehr schön. Als Fortsetzung wäre es interessant, auch die Struktur der Vtable selbst zu reverse-engineeren. Ich vermute, es ist eine Liste von Zeigern auf die Methodenimplementierungen?