我需要打印-而且只打印-用户,使用只接受UTF-8字符串作为输入的系统.

如何以平台无关的方式将OsString转换为UTF8字符串(仅单向)?

我已经找到了Crate encoding,但我找不到一种方法来检测基本的OsString编码.

推荐答案

在阅读了大量的标准库文档和源代码后,我得出了以下结论.

  • 在Unix上,OsStringVec<u8>,可以是任意字节,预计为UTF-8.Windows OsString上当前的版本是WTF-8(source),它是UTF-8的超集,允许您以特定格式的UTF-8表示格式错误的UTF-16.将其理解为也是类似UTF-8的任意字节就足够了,因为只有在恢复原始字节的情况下才使用WTF-8编码的属性(参见下面的encode_wide).如果操作系统中相同的Unicode信息在Unix上以有效的UTF-8编码,在Windows上以有效的UTF-16编码,OsString会将两者编码为相同的UTF-8.这些都是内部的和私有的,但有助于理解公共接口.
  • 用户可见的特定于平台的行为只有在转换时才会出现.
  • 在从操作系统接收时,Windows系统使用from_wide,这会将可能格式错误的UTF-16转换为OsString(WTF-8)编码.Unix系统使用from_vec,它只是包装了Vec<u8>.两者都是无损的,但from_wide确实改变了布局.我认为在Windows上创建&OsStr而不首先创建OsString的唯一方法是从str开始,而在Unix上也可以使用from_bytes从简单的&[u8]切片创建&OsStr.
  • Windows允许您将OsStr转换为具有encode_wide的可能格式错误的UTF-16码点的迭代器,这将无损地undo撤消原始转换.在Unix上,您可以简单地用as_bytesinto_vec取回字节.在Windows上,似乎无法获得&[u8]字节,考虑到实现方式,这是有意义的.
  • 在转换为String时,将判断所有Unicode无效的OsString值的有效性.但是,如果OsString运行在Windows上并且是有效的Unicode,则转换为String将跳过有效性判断,因为这是在最初转换为OsString并作为布尔值存储在OsString中时执行的.此布尔值只有在为真时才有意义,在这种情况下,可以确保OsString是有效的UTF-8.如果它是假的,可能是有效的,也可能是无效的.Unix没有这个布尔值.这意味着,如果你保留OsString,而且它是有效的,在Windows上多次转换为String将比在Unix上更便宜.然而,如果你从操作系统收到OsString个值,但从未将它们转换成String,由于Windows的预先转换,它在Unix上将比Windows便宜.

因此,从本质上讲,有三种 Select :

  1. 操作系统为您提供了有效的字符串.OsString已经是有效的UTF-8,您可以使用into_stringto_str获得这些字节.
  2. 操作系统给了您一个可能无效的字符串.您可以使用前面的方法进行判断,也可以拨打to_string_lossy进行自动替换.
  3. 如果你想知道操作系统为你提供了什么,如果你想使用不同的替换策略,或者如果你想重新解释字节,你可以在Windows上使用encode_wide,或者在Unix上使用as_bytesinto_vec.

Rust相关问答推荐

通用池类型xsx

当为a Self:IntoIterator设置trait bind `时,获取`a T `不是迭代器"&'"<'>&'

常量泛型和类型枚举箱有重叠的用途吗?

从特征实现调用函数的Rust惯用方法

为什么我不能从带有字符串的 struct 的引用迭代器中收集VEC<;&;str&>?

为潜在的下游实现使用泛型绑定而不是没有泛型绑定的trait

如何定义实现同名但返回类型不同的 struct 的函数

通过RabbitMQ取消铁 rust 中长时间运行的人造丝任务的策略

不能在Rust中使用OpenGL绘制三角形

循环访问枚举中的不同集合

为什么HashMap::get和HashMap::entry使用不同类型的密钥?

如何执行数组文字的编译时串联?

如何在 `connect_activate()` 之外创建一个 `glib::MainContext::channel()` 并将其传入?

RUST 中的读写器锁定模式

如何以与平台无关的方式将OsString转换为utf-8编码的字符串?

需要哪些编译器优化来优化此递归调用?

为什么我的trait 对象类型不匹配?

为什么1..=100返回一个范围而不是一个整数?

如何存储返回 Future 的闭包列表并在 Rust 中的线程之间共享它?

编写 TOML 文件以反序列化为 struct 中的枚举