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

Ath*_*ick 73 rust

我想在Rust中编写简单的TCP/IP客户端,我需要打印出从服务器获得的缓冲区.如何将u8矢量转换String为打印?

gav*_*inb 79

要将一片字节转换为字符串切片(假设采用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);
}
Run Code Online (Sandbox Code Playgroud)

转换是就地的,不需要分配.String如有必要,您可以通过调用.to_owned()字符串切片(其他选项可用)从字符串切片创建.

转换函数的库参考:

  • 虽然 `from_utf8` 确实没有分配,但可能值得一提的是它需要扫描数据以验证 utf-8 正确性。所以这不是 O(1) 操作(一开始可能会这么想) (2认同)

Bjo*_*orn 55

我更喜欢String::from_utf8_lossy:

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

它将无效的UTF-8字节转换为 ,因此不需要进行错误处理.这对你不需要的时候很好,我几乎不需要它.你真的得到了一个String.它应该使您从服务器上获得的内容更容易打印出来.

有时您可能需要使用该into_owned()方法,因为它是写入时的克隆.

  • 非常感谢`into_owned()`的建议!正是我正在寻找(这使它成为一个正确的`String`,你可以返回一个方法的返回值,例如). (3认同)

She*_*ter 38

如果你实际上有一个bytes(Vec<u8>)向量并希望转换为a 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);
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!为什么其他两个答案都忽略了这个问题? (2认同)
  • 编辑:请注意,正如@Bjorn Tipling 所提到的,您可能认为您可以在这里使用 `String::from_utf8_lossy` 代替,那么您不需要 `expect` 调用,但它的输入是一个字节片(`&amp; 'a [u8]`)。OTOH,还有`from_utf8_unchecked`。“如果您确定字节切片是有效的 UTF-8,并且您不想招致转换的开销,则此函数有一个不安全的版本 [`from_utf8_lossy]`、`from_utf8_unchecked`,它具有相同的行为,但跳过检查。” (2认同)

Luc*_*lla 10

就我而言,我只需要将数字转换为字符串,而不是根据某种编码将数字转换为字母,所以我这样做了

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