一、String、&str 必须是合法的 UTF-8 格式的 Unicode 字符串
String、&str 变量有个限制,就是只能保存 UTF-8 格式的字符串。这不很正常嘛?实际一用就会发现问题。
二、有些编程语言允许非法 Unicode 字符串存在
如果只考虑 Unicode 的合法编码,String、&str 只能保存 UTF-8 格式的字符串当然没问题。但是, 依据 Unicode 的编码规则可以发现,其编码空间存在不少空白区间,这就构成了“非法”的 Unicode 编码。这些非法编码虽然无法映射成任何语言符号,但是,客观上的确存在这样的编码。或许某个程序猿为了特殊的目的,就硬给你拼出来一个这样的非法字符串。
C、C++ 这类的编程语言并不会在乎字符串编码的合法性,只要你能编出来,它就接受,合法不合法,程序设计语言才不管呢。
但是,Rust 却背起了编码合法性检查的大锅,确保不会出现非法 Unicode 字符串。但是,如果 Rust 在与其他语言对接的时候,如果收到非法字符串,就无法处理了。所以说,多一事不如少一事,不能随意增加功能的内涵,关键时候会自缚手脚。
三、OsString、OsStr 应运而生
万般无奈的情况下,只好新设计一套新的字符串类型,用来在做 FFI 接口的时候放弃字符串合法性检查,并把这种允许非法字符存在的编码格式美其名曰——WTF-8。
根据设计文档,OsString、OsStr 作用分别类似 String 和 &str,但是不再做合法性检查。因此,其他编程语言传过来的字符串,他们照单全收。
最后提供一段代码,供欣赏:
use std::ffi::OsStr;
use std::ffi::OsString;fn main() {let a_str: &str = "Hello Str!"; let an_os_str: &OsStr = OsStr::new(a_str); println!("{:?}", an_os_str); let a_string = String::from("Hello, String!");let an_os_string = OsString::from(a_string); println!("{:?}", an_os_string);
}