编者按:这个代码示例来自Rust 1.0之前的版本,不是有效的Rust 1.0代码,但答案仍然包含有价值的信息.

我想将字符串文本传递给Windows API.许多Windows函数使用UTF-16作为字符串编码,而Rust的原生字符串是UTF-8.

我知道Rust需要utf16_units()才能生成UTF-16字符迭代器,但我不知道如何使用该函数生成最后一个字符为零的UTF-16字符串.

我是这样制作UTF-16字符串的,但我相信有更好的方法来制作它:

extern "system" {
    pub fn MessageBoxW(hWnd: int, lpText: *const u16, lpCaption: *const u16, uType: uint) -> int;
}

pub fn main() {
    let s1 = [
        'H' as u16, 'e' as u16, 'l' as u16, 'l' as u16, 'o' as u16, 0 as u16,
    ];
    unsafe {
        MessageBoxW(0, s1.as_ptr(), 0 as *const u16, 0);
    }
}

推荐答案

rust 1.8+

str::encode_utf16是UTF-16值的稳定迭代器.

你只需要在迭代器上使用collect()来构造Vec<u16>,然后在向量上使用push(0):

pub fn main() {
    let s = "Hello";

    let mut v: Vec<u16> = s.encode_utf16().collect();
    v.push(0);
}

rust 1.0+

str::utf16_units()/str::encode_utf16不稳定.另一种 Select 是切换到夜间(如果您正在编写程序,而不是库,这是一个可行的 Select ),或者使用外部机箱,如encoding:

extern crate encoding;

use std::slice;

use encoding::all::UTF_16LE;
use encoding::{Encoding, EncoderTrap};

fn main() {
    let s = "Hello";

    let mut v: Vec<u8> = UTF_16LE.encode(s, EncoderTrap::Strict).unwrap();
    v.push(0); v.push(0);
    let s: &[u16] = unsafe { slice::from_raw_parts(v.as_ptr() as *const _, v.len()/2) };
    println!("{:?}", s);
}

(如果你想要&mut [u16],也可以使用from_raw_parts_mut).

然而,在这个特定的例子中,你必须小心endianness,因为UTF_16LE编码给你一个代表u16字节的字节向量,以小endian字节顺序,而from_raw_parts技巧允许你"查看"字节向量,作为你平台字节顺序的u16字节片段,也可以是大端字节.如果你想要完全的便携性,使用byteorder这样的 crate 可能会有帮助.

This关于Reddit的讨论可能也会有所帮助.

Rust相关问答推荐

在Tauri中获取ICoreWebView 2_7以打印PDF

在自身功能上实现类似移动的行为,以允许通过大小的所有者进行呼叫(&;mut;self)?

这种获取-释放关系是如何运作的?

如何在Bevy/Rapier3D中获得碰撞机的计算质量?

将serde_json读入`VEC<;T&>;`( rust 色)时出现问题

为什么`AlternateScreen`在读取输入键时需要按Enter键?

如何在AVX2中对齐/旋转256位向量?

如何将带有嵌套borrow /NLL 的 Rust 代码提取到函数中

确保参数是编译时定义的字符串文字

使用启用优化的 alloc 会导致非法指令崩溃

tokio::spawn 有和没有异步块

为什么这个闭包没有实现Fn?

从Rust 的临时文件中创建引用是什么意思?

分配给下划线模式时会发生什么?

有没有办法通过命令获取 Rust crate 的可安装版本列表?

为什么我可以同时传递可变和不可变引用?

当 `T` 没有实现 `Debug` 时替代 `unwrap()`

我可以在不调用 .clone() 的情况下在类型转换期间重用 struct 字段吗?

有没有办法阻止 rust-analyzer 使非活动代码变暗?

如何将 while 循环内的用户输入添加到 Rust 中的向量?