rust - 虽然 Rust 的 char 支持非英文字符,但很多文章推荐使用 string 来存储非英文字符,而不是 char。为什么?
问题描述
我知道 Rust 的 char 存储一个十六进制的 unicode 4 字节码。
和字符串(大部分)由UTF-8(它是重新编译的Unicode)。
那些文章似乎向我表达了使用 char 存储非英文字符很容易出错。但是我找不到任何会引起麻烦的实际代码。
查了一下Unicode、UTF8、UTF32的基础知识。但是我还是不明白,不推荐这种方式
据我了解,在保证代码文件用UTF-8编译时,char和string同时用于存储非英文字符,应该都编译正确。
Rust doc 并没有说不能使用。但他引用了一个非英文字符,可以用一个 Unicode 码点或两个 Unicode 码点表示。它还指出,人类对“字符”的直觉可能无法映射到 Unicode 的定义由于我的语言问题,我的本地文章在此基础上添加了使用 STRING 代替 char 来尽可能存储非英文字符的点。(但他并没有具体的说明,我看到的所有文章都是这样的) é 可以直接使用拉丁文本本身占用的Unicode码位,也可以使用英文的e和一个重音符号。这会导致任何问题吗?如果我使用 char 来存储 é。我应该总是得到一个 Unicode 代码点。我为什么要关心预先组合的字符
解决方案
也许你可以看看UTF-8 Everywhere的解释。
简而言之,您所看到的“角色”通常不是char
. Achar
是一个代码点,而(视觉)字符远比这复杂得多。我引用上述网站(重点是我的):
编码字符,编码字符——编码点和抽象字符之间的映射。[§3.4, D11] 例如,U+1F428 是一个编码字符,代表抽象字符考拉。 这个映射既不是全的,也不是单射的,也不是满射的:
- 代理、非字符和未分配的代码点根本不对应抽象字符。
- 一些抽象字符可以用不同的码点编码;U+03A9 希腊大写字母 omega 和 U+2126 ohm 符号都对应同一个抽象字符
Ω
,必须同等对待。- 一些抽象字符不能由单个代码点编码。这些由编码字符序列表示。例如,
ю́
用锐音表示抽象字符西里尔小写字母 yu 的唯一方法是通过序列 U+044E 西里尔小写字母 yu 后跟 U+0301 组合锐音符。Moreover, for some abstract characters, there exist representations using multiple code points, in addition to the single coded character form. The abstract character
ǵ
can be coded by the single code point U+01F5 latin small letter g with acute, or by the sequence<U+0067 latin small letter g, U+0301 combining acute accent>
.
Do check the site for more details and insights.
Since you specifically asked about the problems for using a char
instead of the more generic String
/str
, I will try to name some:
- There is actually some characters that can only be represented as multiple code points (e.g. some emoji characters);
- Even if you managed to store one in a
char
, you don’t have too much to gain. A&str
should be light-weight enough; - If you ever want to receive input from the user, you had better use a
String
, for you would never know how the “character” is encoded; - Personally, use a
str
/String
is a reminder: text processing is always hard, and the complication in “character” is only a small part.
推荐阅读
- javascript - 使用 PHP 获取由 JavaScript 代码设置的 cookie
- css - 消除首屏内容中的渲染阻塞 CSS
- postgresql - 在数据库上实现大规模调度程序
- java - 使用集合加载 DTO
- spring - 此行有多个标记 - 不推荐使用 NoOpPasswordEncoder 类型 - 不推荐使用 NoOpPasswordEncoder 类型的方法 getInstance()
- java - MySQL CREATE DATABASE IF NOT EXISTS 命令行中的参数
- angular - 为nesjt设置配置的哪种方式更好,ConfigModule还是普通配置模型
- amazon-web-services - 为多个区域 api 网关使用 terraform 模块
- android - 通过另一个适配器访问一个适配器的数据
- ms-word - 格式化Word的方式,以便在距页面边框给定距离处出现一行?