关于SML/NJ中string类型、UTF-8与Unicode的技术问询
Standard ML/SML/NJ 中 Unicode 与 UTF-8 相关问题解答
核心问题解答
1. SML/NJ 中 string 类型的本质
SML标准定义里,char是8位字节,string是char的有序序列——本质就是字节序列。在你的场景中,"søk"作为UTF-8编码的文本被存入string,里面存储的是s(ASCII单字节)、ø(UTF-8双字节:0xC3 0xB8)、k(ASCII单字节)这四个字节的序列,而非单独的Unicode码点。
widestring/widechar是SML/NJ的扩展类型,设计用来直接存储Unicode码点(通常是32位的UCS-4/UTF-32),单个widechar对应一个Unicode码点,widestring是码点的序列。Windows版本缺失该类型,大概率是因为Windows原生wchar_t是16位(对应UTF-16),和SML/NJ的widechar设计不兼容,因此未实现。
2. SML/NJ string 的可移植性
在所有UTF-8环境(如Linux)中完全可用。因为SML/NJ的string存储的是UTF-8编码的字节序列,只要目标环境的输入输出(控制台、文件系统)采用UTF-8编码,直接输出string就能正确显示非ASCII字符,和Windows下的表现一致。比如在Linux下编译运行你提供的代码,控制台会正确打印søk。
3. 不同SML实现的string行为差异
不一致。SML标准仅规定char是8位、string是char序列,并未强制编码规则:
- 部分实现(如Poly/ML)有自己的宽字符扩展类型,对Unicode的处理逻辑不同;
- 有些实现不做编码约束,
string仅作为原始字节序列存在,编码完全由用户控制。
跨实现处理Unicode时,建议统一用UTF-8编码存储string,避免依赖实现特定的行为。
额外困惑解析
string存储的是wchar还是UTF-8字节?
是后者。string是char(8位字节)的序列,你的代码中"søk"是UTF-8编码的字节,print时控制台用UTF-8解析这些字节,所以能正确显示。UTF8结构的作用UTF8结构是处理UTF-8编码的工具集,提供了Unicode码点与UTF-8字节序列之间的转换、UTF-8合法性校验等功能,和C语言的wchar没有直接关联,只是用来辅助处理UTF-8编码的string。- 缺失的
widechar是什么?
如前所述,它是SML/NJ为直接操作Unicode码点设计的32位扩展类型,对应单个Unicode码点,widestring是该类型的序列(类似UTF-32存储),Windows版本因底层API兼容问题未提供。
REPL输入非ASCII字符报错的解决
sml.bat的REPL默认输入处理仅支持ASCII范围内的字符,或输入编码与REPL预期不匹配,导致输入非ASCII字符时触发错误。解决方式:
- 将包含非ASCII字符的代码写入UTF-8编码的
.sml文件; - 在REPL中用
use "你的文件名.sml";加载执行该文件,即可正常处理非ASCII内容。
内容的提问来源于stack exchange,提问作者RandomB
相关产品推荐
相关产品推荐

