如何在Clojure中为汉字使用Unicode字符字面量?U+20BB7问题咨询
关于Clojure中使用增补平面Unicode字符的问题
你猜得没错!在Clojure里,确实没法直接用单个字符字面量(比如\𠮷这种形式)来表示超过U+FFFF的Unicode字符——也就是我们说的增补平面字符,包括你要的U+20BB7。
为什么字符字面量不行?
这本质上和Java的底层实现有关:Clojure的char类型直接对应Java的char,而Java的char是16位的,只能容纳基本多语言平面(BMP,U+0000到U+FFFF)的字符。增补平面的字符需要用UTF-16代理对(两个16位代码单元的组合)来编码,单个char根本装不下完整的增补字符。
可行的解决方案
你已经找到的字符串代理对方式是完全有效的,除此之外还有更直观的代码点生成方式:
直接使用代理对字符串
这是最直接的写法,就像你尝试的那样:"\uD842\uDFB7" ; 这就是U+20BB7对应的UTF-16代理对字符串注意这个字符串的长度是2(对应两个代码单元),但它表示的是单个Unicode字符。
通过Unicode代码点生成
如果不想硬写代理对,可以直接用字符的代码点(0x20BB7)来生成对应的字符串,借助Java的Character/toChars方法:(apply str (Character/toChars 0x20BB7))这个方法会自动把代码点转换成对应的UTF-16代理对字符数组,再拼接成字符串,结果和第一种方式完全一致。
验证一下
你可以用下面的代码确认两种方式的效果:
;; 测试代理对字符串 (def proxy-str "\uD842\uDFB7") (count proxy-str) ; => 2(代码单元数量) (Character/codePointCount proxy-str 0 (count proxy-str)) ; => 1(实际Unicode字符数量) ;; 测试代码点生成的字符串 (def code-point-str (apply str (Character/toChars 0x20BB7))) (= proxy-str code-point-str) ; => true
所以结论是:如果只是静态使用这个字符,代理对字符串就足够了;如果需要动态生成增补平面字符,代码点的方式会更灵活。
内容的提问来源于stack exchange,提问作者Didier A.




