¿Cómo convierto un vector de bytes (u8) en una cadena?


94

Estoy tratando de escribir un cliente TCP / IP simple en Rust y necesito imprimir el búfer que obtuve del servidor.

¿Cómo convierto a Vec<u8>(o a &[u8]) a a String?

Respuestas:


98

Para convertir un segmento de bytes en un segmento de cadena (asumiendo una codificación UTF-8):

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);
}

La conversión está en su lugar y no requiere una asignación. Puede crear un a Stringpartir del segmento de cadena si es necesario llamando .to_owned()al segmento de cadena (hay otras opciones disponibles ).

La referencia de la biblioteca para la función de conversión:


Es posible que desee agregar que esto es posible porque Vec coacciona a las rebanadas
— torkleyy

aunque el código de ejemplo no usa un Vector :-)
— Andrew Mackenzie

Aunque es cierto que from_utf8no se asigna, vale la pena mencionar que necesita escanear los datos para validar la corrección de utf-8. Entonces, esta no es una operación O (1) (que uno puede pensar al principio)
— Zargony

64

Yo prefiero String::from_utf8_lossy:

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

Convierte bytes UTF-8 no válidos en , por lo que no se requiere manejo de errores. Es bueno para cuando no lo necesitas y yo apenas lo necesito. De hecho, obtienes un beneficio Stringde esto. Debería facilitar un poco la impresión de lo que obtiene del servidor.

A veces, es posible que deba usar el into_owned()método, ya que se clona al escribir.


3
¡Muchas gracias por la into_owned()sugerencia! Era exactamente lo que estaba buscando (esto hace que se convierta en un valor adecuado Stringque puede devolver como valor de retorno de un método, por ejemplo).
— Per Lundberg

48

Si realmente tiene un vector de bytes ( Vec<u8>) y desea convertirlo a String, lo más eficiente es reutilizar la asignación con String::from_utf8:

fn main() {
    let bytes = vec![0x41, 0x42, 0x43];
    let s = String::from_utf8(bytes).expect("Found invalid UTF-8");
    println!("{}", s);
}

2
¡Gracias! ¿Por qué las otras dos respuestas ignoraron la pregunta?
— Jehan

1
@Jehan porque la gente generalmente no es buena para hacer preguntas, especialmente cuando son nuevos en un idioma. Rust hace una distinción entre una matriz , una porción y una Vec, pero los recién llegados no conocen las diferencias. Sin embargo, asegúrese de votar a favor de todas las preguntas y respuestas que resulten útiles.
— Shepmaster

Tenga en cuenta que, como lo menciona @Bjorn Tipling, puede usar String::from_utf8_lossyen su lugar aquí, entonces no necesita la llamada esperada .
— James Ray

2
Editar: tenga en cuenta que, como lo menciona @Bjorn Tipling, puede pensar que puede usarlo String::from_utf8_lossyaquí, entonces no necesita la expectllamada, pero la entrada es una porción de bytes (&'a [u8] ). OTOH, también hay from_utf8_unchecked. "Si está seguro de que el trozo byte es UTF-8 válidos, y no quiere incurrir en los gastos generales de la conversión, hay una versión insegura de esta función [ from_utf8_lossy], from_utf8_uncheckedque tiene el mismo comportamiento, pero se salta los controles. "
— James Ray

Tenga en cuenta que puede utilizar &vec_of_bytespara convertir de nuevo en un segmento de bytes, como se indica en los ejemplos de from_utf8_lossy. doc.rust-lang.org/std/string/…
— James Ray
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.