理由
根据我的个人经验,以及观察 Slack 中的初学者频道,新手的极端常见陷阱是想知道如何将字符串解析为整型。
这会在多个方面出错
- 人们发现
int
函数,其文档字符串为 强制转换为整型,传递字符串时会抛出异常。
- 有人建议使用
Integer/parseInt
来执行这项任务,但它不能用作 (map Integer/parseInt coll-of-strings)
,这是令人惊讶的,因为这通常是他们对 Java 集成的第一次体验。
- 有人建议使用
,这符合预期,但其语法对于 Clojure 的前 10 分钟来说可能有点多。
- 有时人们建议使用
,这在 Java 11 中已被弃用。
- 人们在 ClojureScript 中执行相同的操作,并必须选择不同的互操作方式来完成此操作。
建议 1
考虑在 Clojure 中添加一个 parse-*
函数家族,这些函数是在 Java 互操作上的薄包装。附录中可能有这样的列表。
建议 2
考虑将 clojure.lang.LispReader.matchNumber
暴露为 parse-number
。
然后人们可以使用各种强制函数来获取他们需要的精度。这可能更适合这张票据的理由,即使非常常见的“玩具程序”操作对初学者来说更加平滑,并且与读者的行为相匹配将是最不令人惊讶的事情。
对性能敏感的人应该了解 JVM 上装箱算术的复杂性。这也是一个愉悦的平台无关选项,CLJS 可以公开 match-number
。
问题/替代方案
- 函数应该返回原始值还是装箱值?
- 如何处理如
"0xff"
这样的字符串?parseFoo
函数家族拒绝这些,但 0xff
可以通过 Clojure 读取器读取。
- 另一方面,
decode
函数家族处理一些前缀,但它们返回装箱值。但它们还接受像 #10
这样的数字,这是一个无效的 Clojure 文字。
附录
以下是(截至 JVM 8)可能完整的原始返回函数列表:
name args ret-value
parse-int s int
parse-int s, radix int
parse-uint s int
parse-uint s, radix int
parse-long s long
parse-long s, radix long
parse-ulong s long
parse-ulong s, radix long
parse-short s short
parse-short s, radix short
parse-byte s byte
parse-byte s, radix byte
parse-float s float
parse-double s double
无符号功能是在 Java 8 中添加的,因此在较新版本的 Clojure 中使用应该是安全的。较新的 JVM 版本增加了对解析 CharSequence 部分的支持。