请在 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,而不是返回 nil。

*另请参阅:* CLJ-969

11 答案

+2

注释由:richhickey 发布

这将是一个破坏性的变化

+1

即使 {{clojure.core/get}} 的初始设计是混淆/错误的,现在改变也来不及了。这次改变不值得,将会破坏太多程序/库。
我们目前能做的最好方法是创建具有此新行为的 clojure.core/get2my-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 完全相同,但它在最新主分支上应用得更干净。最近的提交 CLJ-1099 将测试中的许多 IllegalArgumentException 发生更改为 Throwable,这是此更新补丁中唯一更改的地方。

0

评论由:jafingerhut

到2014年1月23日为止,补丁 clj-1107-throw-on-get-for-unsupported-types-patch-v2.txt 能够干净地应用到 Clojure 的最新主分支上,但在之后到2014年1月30日之间对 Clojure 的提交中已不再如此。我尚未检查更新此补丁可能有多难或有多简单。

0

评论由:stuart.sierra

从 master 的 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 上下文才能使其干净地应用到最新主分支中。

0
_评论由:stuart.sierra_

CLJ-932 ({{contains?}}) 可能也是如此,它“破坏”了一些已损坏的事物。

这比 CLJ-932 更具侵略性,但我认为它更有可能暴露隐藏的缺陷,而不是破坏预期的行为。
0
_评论由: alex+import_ 提供

使用 "({:a 1}, :a)" 和一个安全的替换方案会更加地道吗?例如,你能否在一个代码库中批量将 "(get " 替换为 "(", 以找到错误吗?我还在学习这门语言,并且不再年轻,因此无法可靠地记住参数的顺序。所以我发现避免 (get) 使用映射更为容易。没有它,我可以将映射放在第一位或第二位。
0

评论由: alexmiller 提供

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

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

我一直认为 (get m k) 等同于 (val (find m k)),但当我发现 m 不是关联性的时,这对我来说非常令人惊讶。

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

我认为 get 在第一个参数不是关联性的时候也应该抛出异常。
对于非关联性参数返回 nil 只会掩盖错误,我想不出任何合理的用例。

...