我目前正在阅读一些 Clojure 代码,其中有一堆未初始化的值:nil
用于传递记录中的数值。
现在有很多 Clojure 库将其视为惯用语 https://stackoverflow.com/questions/6045404/why-clojure-idiom-prefer-to-return-nil-instead-of-empty-list-like-scheme。这意味着这是一个公认的惯例。
但这也导致NullPointerException
,因为并非所有 Clojure 核心函数都可以处理nil
作为输入。 (他们也不应该)。
其他语言有这样的概念Maybe
or Option
在值为空的情况下代理该值,作为减轻NullPointerException
风险。这在 Clojure 中是可能的 -但不是很常见 https://stackoverflow.com/questions/5839697/why-is-the-use-of-maybe-option-not-so-pervasive-in-clojure.
你可以做一些技巧fnil
但这并不能解决所有问题。
另一种选择是将未初始化的值设置为类似的符号:empty-value
强制用户在所有处理代码中显式处理这种情况。但这并不是一个很大的进步nil
- 因为直到运行时你才真正发现所有场景(在其他人的代码中)。
我的问题是:Clojure 中是否有替代 nil 双关语的惯用方法?
不确定你是否读过这篇 lispcastpost http://www.lispcast.com/nil-punning on nil-punning
,但我确实认为它很好地说明了为什么它是惯用的,并且涵盖了我在其他问题中没有看到的各种重要考虑因素。
基本上,nil
is a 头等舱Clojure 中的东西。尽管它具有固有的传统意义,is一个适当的值,并且可以在许多上下文中以依赖于上下文的方式被视为这样。这使得它比null
以宿主语言。
例如,这样的东西甚至无法在 java 中编译:
if(null) {
....
}
在 clojure 中,(if nil ...)
会工作得很好。所以有很多情况可以使用nilsafely。我还没有看到一个 Java 代码库不是这样的littered代码如下if(foo != null) { ...
到处。也许是java 8的Optional
将改变这一点。
我想你在哪里can在 Java 互操作场景中,您正在处理实际的问题,很容易遇到问题null
s。一个好的 clojure 包装库在很多情况下也可以帮助你避免这种情况,这是一个很好的理由prefer如果可能的话,可以通过直接java互操作进行。
鉴于此,您可能需要重新考虑应对这一电流。但既然你问的是替代方案,我认为这是一个很好的选择:棱柱体的图式 https://github.com/Prismatic/schema。架构有一个Maybe
模式(以及许多其他有用的模式),并且它在许多场景中都工作得很好。该库非常受欢迎,我已经成功地使用了它。 FWIW,最近推荐Clojure应用 https://pragprog.com/book/vmclojeco/clojure-applied book.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)