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.

vladimir
quelle
1
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:

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 Foomit 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 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.

BurntSushi5
quelle
6
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.
BurntSushi5