首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >clojure映射中的默认值

clojure映射中的默认值
EN

Stack Overflow用户
提问于 2012-12-11 17:29:36
回答 2查看 8.9K关注 0票数 15

我有一个clojure地图。将其命名为opts。我知道有两种方法可以从这个映射中获取值,这样如果没有键,就可以获得一些默认值:

代码语言:javascript
复制
(let [opts {}
      title-1 (or (:title opts) "Default title")
      title-2 (:title opts "Default title")]
  (println title-1 title-2))

我看到一些库(quil,incanter)在or中使用第一种方法。在我看来,第二种方法更简洁、更干净。第一种方法有优势吗?

使用(or (:title opts) "Default value")的缺点是我们不能再将falsenil作为值传递,在这种情况下总是使用默认值。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-12-11 17:43:20

(or (:key hash) default)(:key hash default)之间的一个重要区别是前者仅在必要时评估default。在后一种情况下,总是对其求值。因此,如果default的计算代价很高,则应该使用or

当您的散列包含在布尔上下文中为假的值时,另一个区别变得很明显。在这些值的情况下,(or (:key hash) default)将被计算为default,而不是您期望的falsenil。与or表达式相反,(:key hash default)将产生正确的结果。顺便说一句,在将nil作为值存储在散列中之前,请三思。

好吧,这些都是重要的区别。现在让我们转到次要的部分。

代码语言:javascript
复制
(or (:title opts) "Default title")

由读取器扩展为

代码语言:javascript
复制
;; Redacted for the sake of brevity.
(let* [x (:title opts)]
  (if x
    x
    "Default title"))

可以说,它比简单地评估效率要低

代码语言:javascript
复制
(:title opts "Default title")

当然,如果没有任何基准,很难估计速度的差异,但我认为它应该是边际的。

另一方面,乍一看,对于不习惯(:key hash :default)习惯用法的人来说,(or (:key hash) :default)似乎更容易理解。考虑一下来自其他语言的程序员。例如,在Ruby中,处理不存在的散列元素的典型方法是

代码语言:javascript
复制
val = hash[:key] || :default

因此,对于不习惯某些Clojure习惯用法的人来说,第一个表达式可能更容易解析。

票数 25
EN

Stack Overflow用户

发布于 2019-10-05 21:19:53

这就是在进行地图析构时使用:or键的原因。

代码语言:javascript
复制
(defn f [{:keys [title-1 title-2] :as opts
          :or {title-1 "default-1" title-2 "default-2"}}]
  (println opts)
  (println title-1)
  (println title-2))

这给了你

代码语言:javascript
复制
> (f {})
{}
default-1
default-2
nil

> (f {:title-1 "foo"})
{:title-1 foo}
foo
default-2
nil

> (f {:title-2 "bar"})
{:title-2 bar}
default-1
bar
nil

> (f {:title-1 "foo" :title-2 "bar"})
{:title-1 foo, :title-2 bar}
foo
bar
nil
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13817244

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档