请在Clojure 2024 状态调查中分享您的想法!

欢迎!请参阅关于页面以了解该工作的更多详细信息。

+27
Clojure
已关闭

理由

根据我的个人经验,以及观察 Slack 中的新手频道,新来者最常见的陷阱之一就是想弄清楚如何将字符串解析为 int。

这出了很多问题

  • 人们发现了 int 函数,其文档字符串是 转换为 int — 如果传递字符串则抛出异常。
  • 人们建议使用 Integer/parseInt,这完成了工作,但不能用作 (map Integer/parseInt coll-of-strings) — 这令人惊讶,因为他们第一次接触 Java 混合。
  • 人们建议使用 #(Integer/parseInt %),它执行预期操作,但其语法对于 Clojure 的前 10 分钟来说可能有点多。
  • 有时人们建议使用 #(Integer. %),这在 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 版本添加了对字符序列部分解析的支持。

已关闭,备注: 在 1.11.0-alpha3 中添加了 parse-long, parse-double, parse-boolean, parse-uuid

2 条回答

+2
by

顺便说一句,我认为我们不太可能添加解析器以匹配所有 Java 类型。但我确实认为拥有这些类型的一部分来匹配读者是有用的。

  • 固定精度的整数 - 总是返回 Long
  • 固定精度的浮点数(总是返回 Double)
  • 整数 - 根据需要匹配读取器 - 返回 Long/BigInteger
  • 浮点数 - 根据需要匹配读取器 - 返回 Double/BigDecimal
  • 数字 - 解析所有数值格式时匹配读取器

但需要更详细的评估。

by
作为更充分的理由,初学者经常遇到 `read-string` 并使用这个。当然可以实现任务,但是有很多问题对于只想将"10"转换为10的初学者来说并不明显。
by
是的,绝对
by
这可能是Java互操作中人们最常做的事情,而且在处理 Advent of Code 或其他练习时,人们第一次遇到这种情况
"parse-*" 名称很可能在程序中频繁出现。与 clojure.core 的冲突不是致命的,但确实讨厌。这些新函数是否应该放入 clojure.string 命名空间以避免冲突?或许需要一个新命名空间?
所有名称/位置待定。
作为一个正在学习 Clojure 的新手,这确实是一个令人困惑的地方。最好知道这是否会在以后的版本中实现。
这些函数在 Clojure 1.11 中添加了 - parse-long, parse-double, parse-boolean, 和 parse-uuid。
0 投票
参考: https://clojure.atlassian.net/browse/CLJ-2451(由 alex+import 报告)
...