尝试获取 Unicode 字符串的长度时,在 RosettaCode 上找到了这个名为 grapheme-length 的代码 [1]。
(def grapheme-length
#(->> (doto (BreakIterator/getCharacterInstance)
(.setText %))
(partial (memfn next))
repeatedly
(take-while (partial not= BreakIterator/DONE))
count))
我使用以下方式在 REPL 中调用它进行测试
(star-traders.util/grapheme-length "\uD83D\uDE04⌘\uD83D\uDE00") ; Expecting 3
它确实返回了预期的值,但我还接收到一个意外的红灯警告,要求我“考虑向 clojure.lang.InjectedInvoker 的维护者报告问题”...
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by clojure.lang.InjectedInvoker/0x0000000800cc8440 (file:/Users/myusername/.m2/repository/org/clojure/clojure/1.10.1/clojure-1.10.1.jar) to method sun.text.RuleBasedBreakIterator.setText(java.text.CharacterIterator)
WARNING: Please consider reporting this to the maintainers of clojure.lang.InjectedInvoker/0x0000000800cc8440
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
显然,这是由于 JVM 添加了 Java 9 模块系统而出现的一个已知问题,并在 Clojure FAQ 中提及 [2]。
尽管如果将--illegal-access=deny
添加到 JVM 参数后问题会消失,但推荐的解决方案是使用类型提示修复代码。
我已尝试使用--illegal-access=warn
定位问题并修复它,如下所示
(.setText ^java.text.BreakIterator %)) ; Problem happens here (I think)
但是问题仍然存在,这让我好奇我应该使用正确的类型。
我应该如何修复代码以去除编译器警告,而不是抑制警告?
[1] https://rosettacode.org/wiki/String_length#Grapheme_Length_2
[2] https://clojure.org/guides/faq#illegal_access