【问题标题】:How do I convert a Vector of bytes (u8) to a string?如何将字节向量 (u8) 转换为字符串?
【发布时间】:2013-10-05 06:47:55
【问题描述】:

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

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

【问题讨论】:

    标签: rust


    【解决方案1】:

    在我的情况下,我只需要将数字转换为字符串,而不是根据某种编码将数字转换为字母,所以我做到了

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

    【讨论】:

    • 这个是我试过的,但是觉得可能有问题什么的。也许我现在会坚持下去。
    【解决方案2】:

    将字节切片转换为字符串切片(假设为 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

    转换函数的库参考:

    【讨论】:

    • 你可能想补充一点,这是可能的,因为 Vec 强制切片
    • 虽然from_utf8确实没有分配,但可能值得一提的是它需要扫描数据来验证utf-8的正确性。所以这不是 O(1) 操作(一开始可能会想到)
    【解决方案3】:

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

    【讨论】:

    • 非常感谢into_owned() 的建议!正是我正在寻找的(这使它成为正确的String,例如,您可以将其作为方法的返回值返回)。
    • � 是 Unicode U+FFFD(UTF-8 序列 0xEF 0xBF 0xBD(八进制 357 277 275)),'REPLACEMENT CHARACTER'。在某些文本编辑器中,可以通过 \x{FFFD} 在正则表达式模式下搜索它。
    【解决方案4】:

    如果您实际上有一个字节向量 (Vec&lt;u8&gt;) 并且想要转换为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);
    }
    

    【讨论】:

    • 编辑:请注意,正如@Bjorn Tipling 所提到的,您可能认为您可以在此处使用String::from_utf8_lossy,那么您不需要expect 调用,但输入是切片字节数 (&amp;'a [u8])。 OTOH,还有from_utf8_unchecked。 “如果您确定字节切片是有效的 UTF-8,并且您不想产生转换的开销,则此函数存在一个不安全版本 [from_utf8_lossy],from_utf8_unchecked,它具有相同的行为但跳过检查。”
    • 请注意,您可以使用&amp;vec_of_bytes 转换回字节切片,如from_utf8_lossy.doc.rust-lang.org/std/string/… 的示例中列出的那样
    • @JamesRay 有没有办法在不重新分配的情况下获得from_utf8_lossy 的行为?如果我以Vec 开头,然后在将其转换为String::from_utf8_lossy(&amp;my_vec) 中的字符串之前对其进行引用,我将在实际上不需要时重新分配内存。
    • 哦,没关系。 from_utf8_lossy 返回 Cow&lt;str&gt;,而不是字符串。如果没有无效字符,则不会重新分配,但如果有,则会重新分配。
    猜你喜欢
    • 2023-02-05
    • 2010-10-17
    • 1970-01-01
    • 2015-03-23
    • 2014-07-14
    • 2021-09-19
    • 1970-01-01
    • 2023-02-26
    • 1970-01-01
    相关资源
    最近更新 更多