首页 新闻 会员 周边 捐助

为什么没有语言就序列化成其他的符号表,所有语言内存中都存的unicode码位表

0
[已关闭问题] 关闭于 2025-08-31 08:59
所有语言在内存里都用 Unicode”并不是谁拍脑袋的规定,而是二十多年踩坑、博弈、统一后的结果。下面把“为什么最终没有其他符号表”拆成四个层面讲清:

1 历史层面:先有万国码,后有“大一统”

  • 1990 年代以前:
    每个国家/平台各玩各的(GB2312、Big5、Shift_JIS、ISO-8859-x、DOS 代码页……)。
    结果:同一封邮件在日、韩、欧、中四台机器上打开,四段乱码。
  • 1991 年 Unicode 联盟成立,目标就是**“一个字符集打天下”**。
    各国标准化组织发现与其继续维护自家碎片,不如合作把字符全塞进 Unicode,于是:
    GBK → GB18030(必须兼容 Unicode),JIS → JIS X 0213(映射到 Unicode),ISO-8859 系列被标记为 legacy。
  • 2000 年以后,主流操作系统(Windows NT/XP、Linux glibc 2.2、macOS 10.2)全部把内核和用户态 wchar 换成 UTF-16/UTF-32,内存里不再保留第二套码位表
  •  

2 技术层面:多一套码位=多一次转换地狱

  • 内存里存两套码位意味着:
    • 每次 I/O 都要做“编码 A → Unicode → 编码 B”的两次查表;
    • 字符串比较、排序、正则、hash 都要先做码位对齐;
    • 出现半个汉字或组合字符时,两套规则可能解释冲突。
  • 性能与复杂度都会爆炸,于是“直接存 Unicode”成了最省事、最不容易出 bug 的方案。
_java_python的主页 _java_python | 小虾三级 | 园豆:984
提问于:2025-08-31 08:58
< >
分享
所有回答(1)
0

3 生态层面:语言运行时、库、协议倒逼

  • 主流语言:
    Java(1996)、C#(2000)、Python 3(2008)、Go(2009)、Rust(2010)……设计之初就把“内部字符串 = Unicode 码位”写进语言规范。
  • 标准库:
    所有正则、排序、大小写转换、文本边界算法(Unicode TR)都默认按 Unicode 走,再维护第二套规则等于重写半个标准库。
  • 网络协议:
    JSON、XML、HTML、YAML、URI、SQL、HTTP header 统统规定“字符层用 Unicode,字节层用 UTF-8/UTF-16”。
    如果某个语言在内存里用别的码位,就必须自己写“转义、编码、解码”的私货,久而久之没人愿意用。

 法律/商业层面:标准组织强推

  • 中国 GB18030(2000 年国家标准)强制要求:
    所有软件必须“能正确输入、显示、存储、交换 Unicode 字符”,否则拿不到销售许可证。
  • 欧盟、美国 FedRAMP 等也要求政务/金融系统支持 Unicode,等于把“非 Unicode 方案”挡在政府采购之外。

任何想继续维护第二套码位的系统,都会面临“没人用、没人维护、到处转码”的死亡循环,于是自然淘汰。

当然运行时高级语言的“字符串对象”存在内存中都是字节,而非字符,运行时内部按某种编码(UTF-8/UTF-16/UTF-32)排布好的字节块,并且对象头里自带“这就是 Unicode”的语义标签,已经不是“一串字节”

序列化阶段先把“字符串对象”里的字节块解码成逻辑码位,

  • 再按序列化协议(JSON、Pickle、Protobuf…)把码位写成协议文本(\u4f60 或原样字符)。
  • 最后按你指定的输出编码(UTF-8、GBK…)把协议文本编码成最终字节序列,写入文件/网络。
_java_python | 园豆:984 (小虾三级) | 2025-08-31 08:59
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册