Nr
Zunächst einmal, wie schon in den Kommentaren erwähnt, können Sie rund um rohe Zeiger werfen nicht wohl oder übel so. Zitieren the documentation of Arc::from_raw
:
Der Rohzeiger zuvor durch einen Aufruf von einem Arc::into_raw
zurück müssen.
Sie unbedingt müssen lesen Sie die Dokumentation jederzeit Sie ein unsafe
Methode verwenden.
Zweitens ist die Konvertierung, die Sie wollen, unmöglich. Vec<T>
→ Box<[T]>
funktioniert, weil intern Vec<T>
effektiv ein (Box<[T]>, usize)
Paar ist. Also gibt Ihnen die ganze Methode Zugriff auf den internen Zeiger Box<[T]>
[1]. Arc<[T]>
ist jedoch nicht physikalisch kompatibel mit einem Box<[T]>
, weil es die Referenzzählungen enthalten muss. Die Sache, auf die durch Arc<T>
gezeigt wird, weist eine andere Größe und ein anderes Layout auf, auf das durch Box<T>
hingewiesen wird.
Die einzige Möglichkeit, die Sie von Vec<T>
bis Arc<[T]>
erhalten, wäre die Neuzuordnung des Inhalts des Vektors in einer Referenz-gezählten Zuweisung ... was mir nicht bekannt ist. Ich glaube nicht, dass es einen bestimmten Grund gibt es konnte nicht umgesetzt werden, es hat einfach nicht [2].
Alles, was gesagt, ich glaube, nicht in der Lage, dynamisch große Typen mit Arc::into_raw
/ ist ein Fehler. Es ist sicherlich möglich, Arc
s mit dynamisch großen Typen zu erhalten ... aber nur durch das Umwandeln von Zeigern in Typen mit fester Größe.
[1]: Nicht ganz. Vec<T>
nicht eigentlich haben eine Box<[T]>
drin, aber es hat etwas kompatibel. Außerdem muss das Segment verkleinert werden, damit es keine nicht initialisierten Elemente enthält.
[2]: Rust hat im Großen und Ganzen keine gute Unterstützung für die Zuweisung von dynamisch großen Dingen im Allgemeinen.Es ist möglich, dass ein Teil des Grundes für dieses Loch insbesondere ist, dass Box<T>
auch Arrays nicht direkt zuordnen kann, was möglicherweise, weil Vec<T>
existiert, weil Vec<T>
verwendet wurde, um Teil der Sprache selbst zu sein, und warum würden Sie Array-Zuweisung hinzufügen zu Box
wenn Vec
bereits existiert? "Warum nicht ArcVec<T>
, dann?" Weil Sie nie konstruieren könnten eins aufgrund der gemeinsamen Besitz.
Vielleicht ist das eine gute Sache: Es wäre UB gewesen, wenn dieser Code kompiliert würde, weil 'Arc :: from_raw' einen Zeiger erwartet, der von' Arc :: into_raw' zurückgegeben wird. Nichtsdestoweniger könnte der Teil, bei dem 'from_raw'' T' benötigt, eine gute Antwort haben. –
@ E_net4 Wirklich? Dann schreiben wir "let x = Box :: new (5);" anstatt im Beispiel wäre UB? – John
Beachten Sie, dass 'Arc :: from_raw()' nur mit einem Wert verwendet werden darf, der von 'Arc :: in_raw()' zurückgegeben wird, weil 'Arc' einen Header vor dem Datenzeiger platziert und' Arc :: from_raw' erwartet diesen Header, indem Sie direkt vor dem von Ihnen angegebenen Zeiger suchen. –