2024 Clojure状况调查!中分享您的想法。

欢迎!请参阅关于页面,了解更多此处的相关信息。

+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

然后人们可以使用各种强制转换函数来获取他们所需的精度。这可能更适合此故障报告的理由,即使非常常见的“玩具程序”操作对初学者来说更加平滑,并且匹配Reader的行为将是最不容易令人惊讶的事情。

对性能敏感的人应该已经知道更多关于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的一部分。

注:在1.11.0-alpha3中添加了parse-long、parse-double、parse-boolean、parse-uuid。

2 个回答

+2

顺便说一句,我认为我们不太可能为所有Java类型添加解析器。但我确实认为拥有这类子集以匹配reader会有用。

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

但是需要更多的评估。

作为进一步的理由,初学者往往会在使用`read-string`时犯错,并使用这个方法。当然可以做这项工作,但有大量问题对新手来说并不明显,他们只想将“10”转换为10。
没错,绝对如此
这可能是最常用的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 报告)
...