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


94

我试图在Rust中编写简单的TCP / IP客户端,我需要打印出从服务器获得的缓冲区。

如何将Vec<u8>(或&[u8])转换为String

Answers:


98

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

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

转换功能的库参考:


您可能想补充一下这是可能的,因为Vec会
强制

尽管示例代码实际上并未使用Vector :-)
Andrew Mackenzie

尽管from_utf8确实没有分配,但值得一提的是它需要扫描数据以验证utf-8的正确性。因此,这不是O(1)操作(
乍一看

64

我更喜欢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()方法,因为它是在写入时克隆的。


3
非常感谢您的into_owned()建议!正是我一直在寻找(例如,这使它成为一种String可以作为方法返回值的属性)。
Per Lundberg

48

如果您实际上有一个字节向量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);
}

2
谢谢!为什么其他两个答案都忽略了这个问题?
Jehan's

1
@Jehan,因为人们通常不善于提出问题,尤其是当他们刚接触某种语言时。Rust区分了arrayslice和a Vec,但是新手并不知道它们之间的区别。确保对所有被证明有用的问题和答案进行投票。
Shepmaster

请注意,正如@Bjorn Tipling所提到的,您可以String::from_utf8_lossy在此处使用它来代替,那么您就不需要Expect 调用了。
James Ray

2
编辑:请注意,正如@Bjorn Tipling所提到的那样,您可能会认为可以String::from_utf8_lossy在此处使用它来代替,那么您不需要expect调用,但是该输入是一片字节(&'a [u8])。OTOH,也有from_utf8_unchecked。“如果你确信字节片是有效的UTF-8,和你不想承担的转换开销,还有这个功能的一个不安全的版本[ from_utf8_lossy]from_utf8_unchecked,它具有相同的行为,但跳过检查。 ”
James Ray

请注意,您可以使用&vec_of_bytes转换回一个字节片,如的示例中所列from_utf8_lossydoc.rust-lang.org/std/string/...
詹姆斯雷
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.