我正在阅读一些Clojure代码,其中包含一堆未初始化的值,就像nil
传入的记录中的数值一样.
现在很多Clojure图书馆都认为这是惯用语.这意味着它是一个公认的惯例.
但它也导致了NullPointerException
,因为并非所有Clojure核心功能都可以处理nil
输入.(也不应该).
其他语言具有Maybe
或者Option
在其为空时代理该值的概念,作为NullPointerException
降低风险的方式.这在Clojure中是可能的 - 但不是很常见.
你可以做一些技巧,fnil
但它并不能解决所有问题.
另一种方法是简单地将未初始化的值设置为符号,:empty-value
以强制用户在所有处理代码中显式处理此场景.但这并不是一个很大的提升nil
- 因为在运行时之前你并没有真正发现所有场景(在其他人的代码中).
我的问题是:在Clojure中是否存在一种惯用的替代品?
不知道是否你读过这lispcast 岗位上nil-punning
,但我认为它使为什么它是地道的一个很好的案例,涵盖我没有看到那些其他SO问题提到的各种重要的考虑因素.
基本上,在clojure中nil
是一流的东西.尽管它具有固有的传统意义,但它是一个适当的价值,并且可以在许多情况下以上下文相关的方式对待.这使它比null
主机语言更灵活,更强大.
例如,像这样的东西甚至不会在java中编译:
if(null) { .... }
在clojure中,(if nil ...)
工作得很好.所以在很多情况下你可以安全地使用nil .我还没有看到,不是Java代码库散落的代码一样if(foo != null) { ...
无处不在.也许java 8 Optional
会改变这一点.
我认为你可以很容易地遇到问题的地方就是你正在处理实际问题的java互操作场景null
.在很多情况下,一个好的clojure包装器库也可以帮助你保护它,并且它是一个很好的理由,在可能的情况下更喜欢直接java互操作.
鉴于此,您可能需要重新考虑对抗此电流.但是既然你在询问替代方案,我认为这是一个很好的方案:棱柱的架构.Schema有一个Maybe
模式(以及许多其他有用的模式),它在很多场景中运行得非常好.该图书馆非常受欢迎,我已成功使用它.FWIW,建议在最近的clojure应用书中.