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

欢迎!请在关于页面上了解有关此功能的一些更多信息。

+1
Clojure
{{clojure.core/get}}的实现在其参数不是关联集合时返回{{nil}}。

此行为可能隐藏常见的编程错误,例如


(def a (atom {:a 1 :b 2}))

(:foo a)   ; 忘了 deref a
;;=> nil


对一个既不是{{nil}}也不是关联集合的对象调用{{get}}几乎肯定是一个漏洞,应通过异常表示。

CLJ-932被接受为类似于{{clojure.core/contains?}}的增强

*补丁:* 0003-CLJ-1107-Throw-exception-for-get-on-unsupported-type.patch

*方法:* 在RT.getFrom中抛出IllegalArgumentException作为最终 fallback 情况,而不是返回 {{nil}}

*另请参阅:* CLJ-969

11 答案

+2

评论者:richhickey

这将是一个破坏性的变化

+1

即使最初的设计{{clojure.core/get}}令人困惑/错误,现在已经来不及改变。这种改变不值得。会破坏太多的程序/库。
我们现在能做的最好的事情就是创建一个带有这种新行为的{{clojure.core/get2}}或{{my-lib.core/get}}。

此外,我无法断言这个get2比我们的get有更好的/更正确的行为。它只是get的另一套规则。当你提出这一新规则集时,有什么保证在另一天,不会有人另行提出新的规则集针对get?也许是一个get3?你怎么知道何时停止呢?

0

评论者:jafingerhut

2013年5月24日的补丁clj-1107-throw-on-get-for-unsupported-types-patch-v2.txt与2012年11月13日的0001-CLJ-1107-Throw-exception-for-get-called-on-unsupport.patch完全相同,除了它能够干净地应用到最新的master。对于CLJ-1099进行的一个最近的提交将测试中的许多IllegalArgumentException实例更改为Throwable,这是此更新补丁唯一的变化。

0

评论者:jafingerhut

补丁clj-1107-throw-on-get-for-unsupported-types-patch-v2.txt在2014年1月23日的Clojure主分支上干净应用,但自那时起至2014年1月30日在Clojure上做出的提交后不再如此。我尚未检查更新此补丁可能有多难或有多容易。

0

评论者:stuart.sierra

从5cc167a的主分支创建的新补丁0003-CLJ-1107-Throw-exception-for-get-on-unsupported-type.patch。

0

评论者:jafingerhut

2014年3月26日的补丁clj-1107-throw-on-unsupported-get-v4.patch与Stuart Sierra的补丁0003-CLJ-1107-Throw-exception-for-get-on-unsupported-type.patch相同,并保留了其作者身份。差异之处仅有一行diff context,以便将其干净地应用到最新的master。

0
_评论者:stuart.sierra_

这在一定程度上也适用于CLJ-932({{contains?}}),它“破坏”了一些已经错误的事物。

这比CLJ-932更具有侵入性,但我觉得它更有可能暴露隐藏的错误,而不是破坏预期的行为。
0
评论由:alex+import_ 提出

使用 "({:a 1}, :a)" 以及一个安全替换启动是否更为地道?例如,能否在一个代码库中将 "(get " 替换为 "(", 以便找到错误?我仍在学习这种语言,而且不再年轻,所以无法可靠地记住参数顺序。因此,我发现在任何情况下都避免使用 (get) 与 maps 会更容易。没有它,我可以将 map 放在第一位或第二位。
0

评论由:alexmiller 提出

现在可能也可以通过一个关于 "get" 的规范来完成。

0
参考:[https://clojure.atlassian.net/browse/CLJ-1107](https://clojure.atlassian.net/browse/CLJ-1107)(由stuart.sierra报告)
-1

我曾经认为 (get m k) 等价于 (val (find m k)),但是当 m 不是关联性时并非如此,这让我非常惊讶。

当 m 不是关联性时,find 会抛出异常,但 get 只返回 nil。

我认为当第一个参数不是关联性时,get 也应该抛出异常。
在非关联参数上返回 nil 只会掩饰错误,我想不出任何有效的用途。

...