理由
根据我的经验,也通过观察 Slack 中的新入门者通道,对于新手来说,一个极为常见的陷阱是想知道如何将字符串解析为整型。
这有多种错误的方式
- 人们发现了 int 函数,其 docstring 为 转换为整型,当传入字符串时会抛出异常。
- 人们建议使用
Integer/parseInt
,它完成了工作,但不能用作 (map Integer/parseInt coll-of-strings)
– 这很令人惊讶,因为这是他们第一次体验 Java 交互。
- 人们建议使用
#(Integer/parseInt %)
,它做预期的事情,但其语法对于前 10 分钟的 Clojure 来说可能有点多。
- 有时人们建议使用
#(Integer. %)
,这在 Java 11 中已被弃用。
- 人们在 ClojureScript 中执行相同的步骤,并必须选择不同的交互方式来执行此操作。
建议 1
考虑在 Clojure 中添加一个 parse-*
系列函数,这类函数是对 Java 交互的高层封装。参见附录以获取可能列表。
建议 2
考虑将 clojure.lang.LispReader.matchNumber
暴露为 parse-number
。
然后人们可以使用各种强制函数来获取他们所需的精度。这可能更适合此票据的论点,该票据的论点是使非常常见的“玩具程序”操作对初学者更平滑,并匹配 Reader 的行为将是 least surprising 的事情。
即使对性能敏感的人也应该了解 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 版本添加了对解析部分 CharSequences 的支持。