虽然 Rust 的 char 支持非英文字符,但是很多文章推荐使用 string 来存储非英文字符而不是 char。为什么?

Although Rust's char supports non-English characters, many articles recommend using string to store non-English characters instead of char. Why?

我知道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的解释。

简而言之,您所看到的“角色”通常不是 charchar 是一个 代码点 ,而(视觉)字符远比这复杂得多。我引用上述网站(重点是我的):

Encoded character, Coded character — A mapping between a code point and an abstract character.[§3.4, D11] For example, U+1F428 is a coded character which represents the abstract character koala. This mapping is neither total, nor injective, nor surjective:

  • Surrogates, noncharacters and unassigned code points do not correspond to abstract characters at all.
  • Some abstract characters can be encoded by different code points; U+03A9 greek capital letter omega and U+2126 ohm sign both correspond to the same abstract character Ω, and must be treated identically.
  • Some abstract characters cannot be encoded by a single code point. These are represented by sequences of coded characters. For example, the only way to represent the abstract character ю́ cyrillic small letter yu with acute is by the sequence U+044E cyrillic small letter yu followed by U+0301 combining acute accent.

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>.

请查看网站以获取更多详细信息和见解。


由于您特别询问了使用 char 而不是更通用的 String/str 的问题,我将尝试列举一些:

  1. 实际上有些字符只能表示为多个代码点(例如一些表情符号字符);
  2. 即使您设法将一个存储在 char 中,您也没有太多收获。一个&str应该够轻便;
  3. 如果你想接收用户的输入,你最好使用String,因为你永远不知道“字符”是如何编码的;
  4. 个人用一个str/String提醒一下:文字处理总是很辛苦,“字符”的复杂只是一小部分。