将Vec <u16>或Vec <WCHAR>转换为&str

Nor*_*ert 7 string rust

我正在进入Rust编程实现一个小程序,我在字符串转换中有点迷失.

在我的程序中,我有一个向量如下:

let mut name: Vec<winnt::WCHAR> = Vec::new(); 
Run Code Online (Sandbox Code Playgroud)

WCHARu16我的Windows机器上的相同.

Vec<u16>将一个C函数(作为指针)移交给数据填充它.然后我需要将向量中包含的字符串转换为 &str.但是,无论我尝试什么,我都无法让这种转换工作.

我设法工作的唯一方法是将其转换为WideString:

 widestr = unsafe { WideCString::from_ptr_str(name.as_ptr()) };
Run Code Online (Sandbox Code Playgroud)

但这似乎是走向错误方向的一步.

在假设向量包含有效且以null结尾的字符串Vec<u16>的情况&str下,将此转换为a的最佳方法是什么.

She*_*ter 12

然后我需要将向量中包含的字符串转换为&str.但是,无论我尝试什么,我都无法让这种转换工作.

没有办法让这个"免费"转换.

A &str是使用UTF-8编码的Unicode字符串.这是一种面向字节的编码.如果您有UTF-16(或不同但常见的UCS-2编码),则无法读取另一个.这相当于尝试将JPEG图像作为PDF读取.两个数据块都可能是一个字符串,但编码很重要.

第一个问题是"你真的需要这样做吗?".很多时候,您可以从一个函数中获取数据并将其转换回另一个函数,从不查看它.如果你可以逃脱,那可能是最好的答案.

如果您确实需要对其进行转换,则必须处理可能发生的错误.任意16位整数数组可能不是有效的UTF-16或UCS-2.这些编码具有边缘情况,可以轻松生成无效字符串.空终止是另一个方面 - Unicode实际上允许嵌入的NUL字符,因此以null结尾的字符串不能容纳所有可能的Unicode字符!

一旦确保编码有效1并确定输入向量中有多少条目构成字符串,则必须解码输入格式并重新编码为输出格式.这可能需要某种新的分配,因此您最有可能最终使用a String,然后可以在任何可以使用的地方&str使用.

有一种内置的方法可以将UTF-16数据转换为String : String::from_utf16. 请注意,它返回a Result以允许这些错误情况.还有String::from_utf16_lossy,它用Unicode替换字符替换无效的编码部分.

let name = [0x68, 0x65, 0x6c, 0x6c, 0x6f]; 

let a = String::from_utf16(&name);
let b = String::from_utf16_lossy(&name);

println!("{:?}", a);
println!("{:?}", b);
Run Code Online (Sandbox Code Playgroud)

如果从指向u16或的指针开始WCHAR,则需要首先使用转换为切片slice::from_raw_parts.如果你有一个以null结尾的字符串,你需要找到NUL你自己并适当地切片输入.


1:这实际上是一种使用类型的好方法; 一个&str保证是UTF-8编码的,所以需要使没有进一步的检查.类似地,WideCString可能在构造时执行一次检查,然后可以跳过对以后使用的检查.

  • @Norbert:我不确定rustaceans是否会把对象称为对象; 每个人都明白这个词,所以它足够好了:) (2认同)