如果 NUL 终止符不在切片的末尾,如何从 NUL 终止的字节切片中获取“&str”?

ide*_*n42 6 string rust

虽然CStr通常用于 FFI,但我正在读取以&[u8]NUL 结尾并确保是有效的 UTF-8,因此不需要检查。

但是 NUL 终止符不一定在切片的末尾。有什么好方法来获得它&str

建议使用CStr::from_bytes_with_nul,但这会在内部\0字符上出现恐慌(当\0不是最后一个字符时)。

oli*_*obk 6

我会使用迭代器适配器来查找第一个零字节的索引:

pub unsafe fn str_from_u8_nul_utf8_unchecked(utf8_src: &[u8]) -> &str {
    let nul_range_end = utf8_src.iter()
        .position(|&c| c == b'\0')
        .unwrap_or(utf8_src.len()); // default to length if no `\0` present
    ::std::str::from_utf8_unchecked(&utf8_src[0..nul_range_end])
}
Run Code Online (Sandbox Code Playgroud)

这样做的主要优点是需要一个来捕获所有情况(例如数组中没有 0)。

如果您想要检查格式良好的 UTF-8 的版本:

pub fn str_from_u8_nul_utf8(utf8_src: &[u8]) -> Result<&str, std::str::Utf8Error> {
    let nul_range_end = utf8_src.iter()
        .position(|&c| c == b'\0')
        .unwrap_or(utf8_src.len()); // default to length if no `\0` present
    ::std::str::from_utf8(&utf8_src[0..nul_range_end])
}
Run Code Online (Sandbox Code Playgroud)