将Vec <u8>投射到&amp; [u16]

时间:2016-03-27 20:02:16

标签: rust

我从文件中读取了Vec<u8>个字节 - 字节是文本格式(可能是UTF-16或其他一些傻2字节格式),我想把它变成UTF-8。

let title = Vec::from_iter(bytes.take(title_length));
// Some Vec<u8> to &[u16] magic
let title = String::from_utf16_lossy(title);

目前我正在使用这个相当脏的代码:

let title: &[u16] = unsafe { std::slice::from_raw_parts(title_data.as_ptr(), title_data.len()) };

虽然这应该可行,但我可能会因take()电话而收到错误:

error: mismatched types:
 expected `*const u16`,
    found `*const core::result::Result<u8, std::io::error::Error>`
(expected u16,
    found enum `core::result::Result`) [E0308]

我应该map take迭代器吗?

3 个答案:

答案 0 :(得分:1)

最后我映射了迭代器的解包,尽管我仍然对迭代器需要包含结果的原因感到困惑。

let title_data = Vec::from_iter(bytes.take(title_length).map(|x| x.unwrap()));
let title: &[u16] = unsafe {
    std::slice::from_raw_parts(title_data.as_ptr() as *const u16, title_data.len() / 2)
};
let title = String::from_utf16_lossy(title);

答案 1 :(得分:0)

有两个错误。首先,您需要.unwrap() Result(我认为是from_raw_parts(..)),其次是长度太大,因为u16占用u8的两倍空间1}},所以你需要除以2。

答案 2 :(得分:0)

使用安全密码

以防万一您需要安全地进行操作,

let title = Vec::from_iter(bytes.take(title_length));
let title: Vec<u16> = title
    .chunks_exact(2)
    .into_iter()
    .map(|a| u16::from_ne_bytes([a[0], a[1]]))
    .collect();
let title = title.as_slice();
let title = String::from_utf16_lossy(title);

请注意,这将分配内存并进行额外的复制(不安全的替代方法则不会这样做)。