rust 如何将字节向量(u8)转换为字符串?

brvekthn  于 2022-11-12  发布在  其他
关注(0)|答案(5)|浏览(464)

我正在尝试写简单的TCP/IP客户端在生 rust ,我需要打印出缓冲区,我从服务器。
如何将Vec<u8>(或&[u8])转换为String

smtd7mpg

smtd7mpg1#

要将字节切片转换为字符串切片(假定使用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);
}

转换是就地进行的,不需要分配。如果需要,可以通过在字符串切片(other options are available)上调用.to_owned(),从字符串切片创建String
如果您确定字节片是有效的UTF-8,并且不想产生有效性检查的开销,那么这个函数有一个不安全的版本from_utf8_unchecked,它具有相同的行为,但是跳过了检查。
如果你需要一个字符串而不是&str,你也可以考虑用String::from_utf8代替。
转换函数的库引用:

jc3wubiy

jc3wubiy2#

我更喜欢String::from_utf8_lossy

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

它把无效的UTF-8字节转换成,所以不需要错误处理。当你不需要它的时候,它很好,我几乎不需要它。你实际上从这里得到了一个String。它应该会让你从服务器上打印出来更容易。
有时您可能需要使用into_owned()方法,因为它是写时克隆的。

gpnt7bae

gpnt7bae3#

如果您实际上有一个 vector of bytesVec<u8>),并希望转换为String,则最有效的方法是使用String::from_utf8重复使用分配:

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

juud5qan4#

在我的例子中,我只需要把数字变成一个字符串,而不是根据某种编码把数字变成字母,所以我这样做了

fn main() {
    let bytes = vec![0x41, 0x42, 0x43];
    let s = format!("{:?}", &bytes);
    println!("{}", s);
}
w7t8yxp5

w7t8yxp55#

为了将可能包含非UTF-8字符/字节序列的Vec<u8>最优地转换为UTF-8 String *,而不需要任何不必要的分配 *,您将希望乐观地尝试调用String::from_utf8(),然后求助于String::from_utf8_lossy()

let buffer: Vec<u8> = ...;

let utf8_string = String::from_utf8(buffer)
    .map_err(|non_utf8| String::from_utf8_lossy(non_utf8.as_bytes()).into_owned())
    .unwrap();

其他答案中建议的方法将导致内存中有 * 两个 * 自有缓冲区,即使是在理想情况下(向量中有有效的UTF-8数据):一个是原始的u8字节,另一个是拥有其字符的String形式。这种方法将尝试使用Vec<u8>并直接将其封送为Unicode String,只有在失败时,它才会为包含有损UTF-8解码输出的新字符串分配空间。

相关问题