Array ein struct-Feld
Möchte ich zu einer non-binary-tree-Struktur in Rost. Hier ist ein try -
struct TreeNode<T> {
tag : T,
father : Weak<TreeNode<T>>,
childrenlists : [Rc<TreeNode<T>>]
}
Leider nicht kompilieren.
main.rs:4:1: 8:2 error: the trait `core::marker::Sized` is not implemented for the type `[alloc::rc::Rc<TreeNode<T>>]` [E0277]
main.rs:4 struct TreeNode<T> {
main.rs:5 tag : T,
main.rs:6 father : Weak<TreeNode<T>>,
main.rs:7 childrenlist : [Rc<TreeNode<T>>]
main.rs:8 }
main.rs:4:1: 8:2 note: `[alloc::rc::Rc<TreeNode<T>>]` does not have a constant size known at compile-time
main.rs:4 struct TreeNode<T> {
main.rs:5 tag : T,
main.rs:6 father : Weak<TreeNode<T>>,
main.rs:7 childrenlist : [Rc<TreeNode<T>>]
main.rs:8 }
error: aborting due to previous error
Der code wird kompiliert, wenn wir ersetzen Sie ein array mit einem Vec
. Doch die Struktur ist unveränderlich, und ich brauche nicht eine überlastete Vec
.
Hörte ich, könnte es möglich sein, auf ein struct-Feld mit einer Größe von unbekannt ist zur compile-Zeit, sofern es eindeutig ist. Wie können wir es tun?
- Ich dachte die Vorgabe war die "Letzte", aber trotzdem ist es auch hier der Fall. Ich fand reddit.com/r/rust/comments/357ji5/...
- In Rost, arrays eine Feste Größe haben, zur Kompilierzeit bekannt ist. Damit Sie nicht möchten, dass ein "array".
&[T]
ist in der Regel als eine Scheibe, ich weiß nicht, wie auszusprechen[T]
. - Ich denke, das wäre "ohne Größenangabe array".
Du musst angemeldet sein, um einen Kommentar abzugeben.
Rost nicht haben, das Konzept einer variable-Länge (Stapel) - array, die Sie scheinen, zu versuchen, hier zu verwenden.
Rost hat ein paar verschiedene array-ish Arten.
Vec<T>
("Vektor"): Dynamisch Größe; dynamisch auf dem heap zugeordnet. Dies ist wahrscheinlich, was Sie verwenden möchten. Initialisieren Sie es mitVec::with_capacity(foo)
zu vermeiden overallocation (erstellt einen leeren Vektor mit der angegebenen Kapazität).[T; n]
("array"): Statisch dimensioniert; lebt auf dem Stapel. Sie müssen wissen, die Größe zur compile-Zeit, so wird dies nicht für Sie arbeiten (es sei denn, ich habe misanalysed Ihrer situation).[T]
("slice"): ohne Größenangabe; in der Regel verwendet von&[T]
. Dies ist ein Blick in einen zusammenhängenden Satz vonT
s im Speicher irgendwo. Sie können es, indem Sie eine Referenz auf ein array oder einen Vektor (genannt "nehmen eine Scheibe von einem array/vector"), oder sogar unter eine Ansicht in eine Teilmenge des Arrays/Vektors. Wird ohne Größenangabe,[T]
können nicht direkt verwendet werden wie eine variable (es kann verwendet werden, als Mitglied einer ohne Größenangabe struct), aber Sie können es hinter einem Zeiger. Zeiger verweisen auf[T]
sind Fett ; d.h. Sie haben einen extra Bereich für die Länge.&[T]
wäre nützlich, wenn Sie möchten, speichern Sie einen Verweis auf ein vorhandenes array; aber ich glaube nicht, dass das, was Sie wollen, hier zu tun.[T]
. Ich denke, das ist eine fehlende information, als ich sah, wie es nirgendwo sonst.Wenn Sie nicht wissen, die Größe der Liste im Voraus, haben Sie zwei Möglichkeiten:
&[T]
das ist nur ein Verweis auf ein Stück der Erinnerung, die Sie nicht selbstVec<T>
die Ihre eigenen Speicher.Die richtige Sache hier ist die Verwendung eines
Vec
. Warum? Weil Sie wollen, dass die Kinder Liste (array vonRc
), um tatsächlich im Besitz derTreeNode
. Wenn Sie ein&[T]
es bedeutet, dass jemand anderes würde sich um die Liste, nicht dieTreeNode
. Mit einigen lifetime Tricks, könnten Sie schreiben ein Gültiger code, aber Sie würde sehr weit zu gehen, um bitte der compiler, weil das geliehene Referenz würde gültig sein, mindestens so lange, wie dieTreeNode
.Schließlich, einen Satz in Ihrer Frage zeigt sich ein Missverständnis:
Du verwirrst Wandelbarkeit und Eigenverantwortung. Sicher, Sie haben eine unveränderliche Vec. Es scheint, wie Sie es vermeiden möchten, reservieren von Speicher aus dem heap, aber das ist nicht möglich, gerade weil Sie nicht wissen, die Größe der Kinder-Liste. Nun, wenn Sie besorgt sind, mit overallocating, können Sie die Feinabstimmung der Vektor-Speicher mit Methoden wie
with_capacity()
undshrink_to_fit()
.Eine Letzte Notiz: wenn Sie wirklich wissen, die Größe der Liste, weil es ist fest zur compile-Zeit, die Sie gerade benötigen, um ein
[T; n]
won
ist compile-Zeit bekannt. Aber das ist nicht das gleiche wie[T]
.