我有一张clojure地图.说出来opts
.我知道从这个地图获取值的两种方法,如果没有键获得一些默认值:
(let [opts {}
title-1 (or (:title opts) "Default title")
title-2 (:title opts "Default title")]
(println title-1 title-2))
Run Code Online (Sandbox Code Playgroud)
我看到一些库(quil,incanter)使用第一种方法or
.在我看来,第二种方法更简洁,更清洁.第一种方法有优势吗?
使用的缺点(or (:title opts) "Default value")
是我们不能再传递false
和nil
作为值,在这种情况下总是使用默认值.
Jan*_*Jan 22
两者之间的关键区别在于(or (:key hash) default)
,(:key hash default)
前者default
仅在必要时进行评估.在后一种情况下,它总是被评估.因此,or
如果评估default
费用昂贵,您应该使用.
当您的哈希包含布尔上下文中的false值时,另一个区别变得明显.在这种情况下,(or (:key hash) default)
将评估default
代替您false
或nil
您期望的值.与or
表达式相反,(:key hash default)
将产生正确的结果.作为旁注,在将nil
值作为值存储在哈希中之前请三思而后行.
好吧,那些是重要的区别.现在让我们转向次要的.
(or (:title opts) "Default title")
Run Code Online (Sandbox Code Playgroud)
由读者扩展到
;; Redacted for the sake of brevity.
(let* [x (:title opts)]
(if x
x
"Default title"))
Run Code Online (Sandbox Code Playgroud)
可以说,它比简单评估效率低
(:title opts "Default title")
Run Code Online (Sandbox Code Playgroud)
当然没有任何基准,很难估计差异是速度,但我认为它应该是微不足道的.
另一方面,(or (:key hash) :default)
对于不(:key hash :default)
熟悉习语的人来说,乍一看似乎更容易理解.考虑来自其他语言的程序员.例如,在Ruby中,处理散列的非存在元素的典型方法是
val = hash[:key] || :default
Run Code Online (Sandbox Code Playgroud)
因此,第一个表达可能更容易被不习惯某些Clojure成语的人解析.