Skip to Content

Unicode 与字形簇(Grapheme Cluster)

MushScript 的字符单位不是码点,是扩展字形簇(Extended Grapheme Cluster)。字符串的 Length、下标、切片与方法面全部按簇计数。

一个「字」可能不止一个码点

print("e\u{301}".Length, "é".Length, "e\u{301}" == "é"); print("甲".Length, "👨‍👩‍👧".Length);
1 1 False 1 1

e 加组合锐音符是两个码点,拼出来的人眼字符是一个簇,Length 为 1。预组合的 é 同样是一个簇。但两者不是同一个值:字符串等值按码点序列精确比较,语言不做隐式 NFC 归一化。emoji 也一样:一家三口的组合 emoji 是一长串码点,簇数是 1。

按簇遍历与取簇

val s = "aé甲🚀"; for c in s { print("簇", c); } print(s.CharAt(1), s.CharAt(3)); print(s.Substr(0, 2));
簇 a 簇 é 簇 甲 簇 🚀 é 🚀 aé

for-in 逐簇产出,CharAt(下标) 按簇号取字,Substr 的起止也按簇算。中文、emoji、组合字符按同一簇规则处理,不会出现「取半个字」。

码点与 ASCII 助手

print("hello".CodePointAt(0), "甲".CodePointAt(0)); print('a'.IsAsciiLetter(), '5'.IsAsciiDigit(), 'x'.ToAsciiUpper());
104 30002 True True X

需要底层码点时用 CodePointAt(下标),它返回该簇首标量的码点。char 的 ASCII 分类与大小写转换挂在 char 上直接可调:IsAsciiDigit / IsAsciiLetter / IsAsciiUpper / IsAsciiLower / ToAsciiUpper / ToAsciiLower。

注意

  • 插值与格式化不区分簇,孔里放什么值按值的字符串化规则来。
最后更新于 2026年10月10日