Wie erstelle ich eine Rust-Struktur mit String-Mitgliedern?
72
Ich möchte, dass die Mitglieder der Struktur gehören. Entschuldigung für die einfache Frage, aber ich konnte kein Beispiel finden. Ich suche nach der richtigen Deklaration einer Struktur und Instanziierungsbeispielen.
Verwenden Sie Stringund beachten Sie, dass das Erstellen eines StringFrom- &strVia .to_string()eine Heap-Zuweisung und das Kopieren der gesamten Zeichenfolge umfasst.
Sellibitze
Antworten:
110
Wenn die Zeichenfolge der Struktur gehören muss, sollten Sie verwenden String. Alternativ können Sie eine &strmit einer statischen Lebensdauer (dh der Lebensdauer des Programms) verwenden. Zum Beispiel:
structFoo {
bar: String,
baz: &'staticstr,
}
fnmain() {
let foo = Foo {
bar: "bar".to_string(),
baz: "baz",
};
println!("{}, {}", foo.bar, foo.baz);
}
Wenn die Lebensdauer der Zeichenfolge unbekannt ist, können Sie Foomit einer Lebensdauer parametrisieren :
Wenn Sie nicht sicher sind, ob die Zeichenfolge im Besitz ist oder nicht (nützlich, um Zuweisungen zu vermeiden), können Sie Folgendes verwenden borrow::Cow:
Beachten Sie, dass der CowTyp über eine Lebensdauer parametrisiert wird. Die Lebensdauer bezieht sich auf die Lebensdauer der geliehenen Zeichenfolge (dh wenn es sich um eine handelt Borrowed). Wenn Sie eine haben Cow, können Sie eine verwenden borrowund erhalten &'a str, mit der Sie normale Zeichenfolgenoperationen ausführen können, ohne sich Gedanken darüber machen zu müssen, ob eine neue Zeichenfolge zugewiesen werden soll oder nicht. In der Regel ist ein explizites Aufrufen von borrowaufgrund von Deref-Zwängen nicht erforderlich. CowWerte werden nämlich automatisch von ihrer geliehenen Form dereferenziert, sodass &*valbei einem valTyp Cow<'a, str>ein a erzeugt wird &str.
Uhhh, danke für die vollständige Antwort. Ich muss an einem anderen Tag über die lebenslange Parametrisierung nachdenken :)
Vladimir
1
Wenn ich eine Struktur habe, die das Copy-Attribut enthält (z. B. # [ableiten (Klonen, Kopieren)], wird der String nicht kompiliert. Was ist die beste Lösung?
tatmanblue
3
String nicht verwenden? Das mag wie eine knappe Antwort erscheinen, aber die Art und Weise, wie Sie Ihre Frage gestellt haben, lässt mir nicht viel Auswahl. Ich vermute, Sie treffen eine Instanz des XY-Problems. Ich würde empfehlen, eine neue Frage zu stellen, in der das eigentliche Problem aufgeführt ist, das Sie lösen möchten.
BurntSushi5
Die Dokumentation besagt, dass Stringveränderlich ist. Wenn ich eine Struktur mit beispielsweise einem nameFeld habe, das unveränderlich sein sollte, sollte ich sie trotzdem Stringanstelle von verwenden str?
Ondra K.
Ich sehe nicht, wie wichtig das für diese Frage ist. Ich würde vorschlagen, dass Sie eine neue Frage stellen.
String
und beachten Sie, dass das Erstellen einesString
From-&str
Via.to_string()
eine Heap-Zuweisung und das Kopieren der gesamten Zeichenfolge umfasst.Antworten:
Wenn die Zeichenfolge der Struktur gehören muss, sollten Sie verwenden
String
. Alternativ können Sie eine&str
mit einer statischen Lebensdauer (dh der Lebensdauer des Programms) verwenden. Zum Beispiel:struct Foo { bar: String, baz: &'static str, } fn main() { let foo = Foo { bar: "bar".to_string(), baz: "baz", }; println!("{}, {}", foo.bar, foo.baz); }
Wenn die Lebensdauer der Zeichenfolge unbekannt ist, können Sie
Foo
mit einer Lebensdauer parametrisieren :struct Foo<'a> { baz: &'a str, }
Siehe auch:
Wenn Sie nicht sicher sind, ob die Zeichenfolge im Besitz ist oder nicht (nützlich, um Zuweisungen zu vermeiden), können Sie Folgendes verwenden
borrow::Cow
:use std::borrow::Cow; struct Foo<'a> { baz: Cow<'a, str>, } fn main() { let foo1 = Foo { baz: Cow::Borrowed("baz"), }; let foo2 = Foo { baz: Cow::Owned("baz".to_string()), }; println!("{}, {}", foo1.baz, foo2.baz); }
Beachten Sie, dass der
Cow
Typ über eine Lebensdauer parametrisiert wird. Die Lebensdauer bezieht sich auf die Lebensdauer der geliehenen Zeichenfolge (dh wenn es sich um eine handeltBorrowed
). Wenn Sie eine habenCow
, können Sie eine verwendenborrow
und erhalten&'a str
, mit der Sie normale Zeichenfolgenoperationen ausführen können, ohne sich Gedanken darüber machen zu müssen, ob eine neue Zeichenfolge zugewiesen werden soll oder nicht. In der Regel ist ein explizites Aufrufen vonborrow
aufgrund von Deref-Zwängen nicht erforderlich.Cow
Werte werden nämlich automatisch von ihrer geliehenen Form dereferenziert, sodass&*val
bei einemval
TypCow<'a, str>
ein a erzeugt wird&str
.quelle
String
veränderlich ist. Wenn ich eine Struktur mit beispielsweise einemname
Feld habe, das unveränderlich sein sollte, sollte ich sie trotzdemString
anstelle von verwendenstr
?