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

人们可以使用各种转换函数来获取所需的精度。这可能更适合此票的理由,即使它旨在使初学者常见的“玩具程序”操作更流畅,并与读者的行为相匹配将是令人最惊讶的事情。

对于性能敏感的人来说,他们可能已经知道 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 部分的解析支持。

关闭注释: 在 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。
参考: https://clojure.atlassian.net/browse/CLJ-2451 (由alexmiller报告)
...