【发布时间】:2013-10-05 06:47:55
【问题描述】:
我正在尝试用 Rust 编写简单的 TCP/IP 客户端,我需要打印出从服务器获得的缓冲区。
如何将Vec<u8>(或&[u8])转换为String?
【问题讨论】:
标签: rust
我正在尝试用 Rust 编写简单的 TCP/IP 客户端,我需要打印出从服务器获得的缓冲区。
如何将Vec<u8>(或&[u8])转换为String?
【问题讨论】:
标签: rust
在我的情况下,我只需要将数字转换为字符串,而不是根据某种编码将数字转换为字母,所以我做到了
fn main() {
let bytes = vec![0x41, 0x42, 0x43];
let s = format!("{:?}", &bytes);
println!("{}", s);
}
【讨论】:
将字节切片转换为字符串切片(假设为 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。
转换函数的库参考:
【讨论】:
from_utf8确实没有分配,但可能值得一提的是它需要扫描数据来验证utf-8的正确性。所以这不是 O(1) 操作(一开始可能会想到)
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,例如,您可以将其作为方法的返回值返回)。
\x{FFFD} 在正则表达式模式下搜索它。
如果您实际上有一个字节向量 (Vec<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);
}
【讨论】:
String::from_utf8_lossy,那么您不需要expect 调用,但输入是切片字节数 (&'a [u8])。 OTOH,还有from_utf8_unchecked。 “如果您确定字节切片是有效的 UTF-8,并且您不想产生转换的开销,则此函数存在一个不安全版本 [from_utf8_lossy],from_utf8_unchecked,它具有相同的行为但跳过检查。”
&vec_of_bytes 转换回字节切片,如from_utf8_lossy.doc.rust-lang.org/std/string/… 的示例中列出的那样
from_utf8_lossy 的行为?如果我以Vec 开头,然后在将其转换为String::from_utf8_lossy(&my_vec) 中的字符串之前对其进行引用,我将在实际上不需要时重新分配内存。
from_utf8_lossy 返回 Cow<str>,而不是字符串。如果没有无效字符,则不会重新分配,但如果有,则会重新分配。