我正在尝试使用Rust编写简单的TCP/IP客户端,需要打印从服务器获得的缓冲区。
如何将Vec<u8>
(或&[u8]
)转换为String
?
我正在尝试使用Rust编写简单的TCP/IP客户端,需要打印从服务器获得的缓冲区。
如何将Vec<u8>
(或&[u8]
)转换为String
?
将一个字节切片转换为字符串切片(假设采用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);
}
此转换是原地进行的,不需要分配内存。如果需要,您可以通过在字符串切片上调用.to_owned()
方法来创建一个String
字符串(还有其他可选项)。
如果您确定字节切片是有效的UTF-8,并且您不想产生有效性检查的开销,则该函数有一个不安全版本from_utf8_unchecked
,它具有相同的行为但跳过了检查。
如果您需要一个String
而不是&str
,您也可以考虑使用String::from_utf8
。
转换函数的库引用:
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
对象,例如可以作为方法的返回值)。 - Per Lundberg\x{FFFD}
进行搜索。 - Peter Mortensen如果您实际上有一个字节向量(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]
)。另一方面,也有from_utf8_unchecked
。如果您确定字节片是有效的UTF-8,并且不希望承担转换开销,那么有一种不安全的版本[from_utf8_lossy
] from_utf8_unchecked
,它具有相同的行为但跳过了检查。 - James Ray&vec_of_bytes
将其转换回字节切片,如from_utf8_lossy
的示例所列。https://doc.rust-lang.org/std/string/struct.String.html#method.from_utf8_lossy - James RayVec
开始,然后在将其转换为字符串之前对其进行引用,例如String::from_utf8_lossy(&my_vec)
,那么当我实际上不需要时,我将最终重新分配内存。 - Michael Dorstfrom_utf8_lossy
返回的是 Cow<str>
,而不是 String
。如果没有无效字符,则不会重新分配内存,但如果有,则会重新分配。 - Michael Dorstfn main() {
let bytes = vec![0x41, 0x42, 0x43];
let s = format!("{:?}", &bytes);
println!("{}", s);
}
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();
v.iter().map(|&c| char::from(c)).collect()
String
被保证完全是UTF-8编码的。如果你想要部分UTF-8编码的内容,可以将其保留为Vec<u8>
。你可以使用像bstr
这样的crate来对其进行各种字符串操作。 - Chayim Friedman
from_utf8
确实不会分配内存,但值得一提的是它需要扫描数据以验证 utf-8 的正确性。因此,这不是一个 O(1) 操作(一开始可能会误以为是)。 - Zargony