Wie konvertiere ich einen Vektor von Bytes (u8) in eine Zeichenfolge?

94

Ich versuche, einen einfachen TCP / IP-Client in Rust zu schreiben, und ich muss den Puffer ausdrucken, den ich vom Server erhalten habe.

Wie konvertiere ich ein Vec<u8>(oder ein &[u8]) in ein String?

Athabaska Dick
quelle

Antworten:

98

So konvertieren Sie ein Byte-Slice in ein String-Slice (unter der Annahme einer UTF-8-Codierung):

use std::str;

//
// pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error>
//
// Assuming buf: &[u8]
//

fn main() {

    let buf = &[0x41u8, 0x41u8, 0x42u8];

    let s = match str::from_utf8(buf) {
        Ok(v) => v,
        Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
    };

    println!("result: {}", s);
}

Die Konvertierung ist vorhanden und erfordert keine Zuordnung. Sie können Stringbei Bedarf ein aus dem String-Slice erstellen, indem Sie .to_owned()das String-Slice aufrufen ( andere Optionen sind verfügbar ).

Die Bibliotheksreferenz für die Konvertierungsfunktion:

Gavinb
quelle
Sie können hinzufügen, dass dies möglich ist, weil Vec zu Scheiben
zwingt
obwohl der Beispielcode eigentlich keinen Vektor verwendet :-)
Andrew Mackenzie
Obwohl es stimmt, dass from_utf8keine Zuordnung erfolgt, kann es erwähnenswert sein, dass die Daten gescannt werden müssen, um die Richtigkeit von utf-8 zu überprüfen. Dies ist also keine O (1)
-Operation
64

Ich bevorzuge String::from_utf8_lossy:

fn main() {
    let buf = &[0x41u8, 0x41u8, 0x42u8];
    let s = String::from_utf8_lossy(buf);
    println!("result: {}", s);
}

Ungültige UTF-8-Bytes werden in umgewandelt, sodass keine Fehlerbehandlung erforderlich ist. Es ist gut, wenn du das nicht brauchst und ich es kaum brauche. Sie bekommen tatsächlich eine Stringdavon. Dies sollte das Ausdrucken der vom Server erhaltenen Daten etwas vereinfachen.

Manchmal müssen Sie die into_owned()Methode möglicherweise verwenden , da sie beim Schreiben geklont wird.

Björn
quelle
3
Vielen Dank für den into_owned()Vorschlag! War genau das, Stringwonach ich gesucht habe (dies macht es zu einem Eigenwert, den Sie beispielsweise als Rückgabewert von einer Methode zurückgeben können).
Per Lundberg
47

Wenn Sie tatsächlich einen Vektor von bytes ( Vec<u8>) haben und in a konvertieren möchten String, ist es am effizientesten, die Zuordnung wiederzuverwenden mit String::from_utf8:

fn main() {
    let bytes = vec![0x41, 0x42, 0x43];
    let s = String::from_utf8(bytes).expect("Found invalid UTF-8");
    println!("{}", s);
}
Shepmaster
quelle
2
Vielen Dank! Warum haben die beiden anderen Antworten die Frage ignoriert?
Jehan
1
@Jehan, weil die Leute im Allgemeinen nicht gut darin sind, Fragen zu stellen, besonders wenn sie neu in einer Sprache sind. Rust unterscheidet zwischen einem Array , einem Slice und einem Vec, aber Neulinge kennen die Unterschiede nicht. Stellen Sie sicher, dass Sie alle Fragen und Antworten, die sich jedoch als nützlich erweisen, positiv bewerten.
Shepmaster
Beachten Sie, dass Sie, wie von @Bjorn Tipling erwähnt, String::from_utf8_lossystattdessen hier verwenden können, dann benötigen Sie den Expect-Aufruf nicht.
James Ray
2
Bearbeiten: Beachten Sie, dass Sie, wie von @Bjorn Tipling erwähnt, vielleicht denken, dass Sie String::from_utf8_lossystattdessen hier verwenden können, dann brauchen Sie den expectAufruf nicht, aber die Eingabe dazu ist ein Stück Bytess ( &'a [u8]). OTOH gibt es auch from_utf8_unchecked. "Wenn Sie sicher sind, dass das Byte-Slice UTF-8 gültig ist und Sie keinen Overhead für die Konvertierung verursachen möchten, gibt es eine unsichere Version dieser Funktion [ from_utf8_lossy], from_utf8_uncheckeddie dasselbe Verhalten aufweist, aber die Überprüfungen überspringt. ""
James Ray
Beachten Sie, dass Sie die &vec_of_bytesKonvertierung in eine Byte-Schicht verwenden können, wie in den Beispielen von aufgeführt from_utf8_lossy. doc.rust-lang.org/std/string/…
James Ray