说我有这张表格的地图:
(def m {:a "A" :b "B"})
Run Code Online (Sandbox Code Playgroud)
我想做一些事情,如果:a并且:b都不是零,我可以这样做:
(if-let [a (:a m)]
(if-let [b (:b m)]
... etc ))
Run Code Online (Sandbox Code Playgroud)
要么
(if (and (:a m) (:b m))
(let [{a :a b :b} m]
... etc ))
Run Code Online (Sandbox Code Playgroud)
甚至
(if (every? m [:a :b])
(let [{a :a b :b} m]
... etc ))
Run Code Online (Sandbox Code Playgroud)
是否有更简洁(即一线)的方式来实现这一目标?
当我使用if-let之类的时候
(if-let [a 2 b nil] (+ a b))
Run Code Online (Sandbox Code Playgroud)
我得到一个IllegalArgumentException:
clojure.core/if-let requires exactly 2 forms in binding vector...
Run Code Online (Sandbox Code Playgroud)
类似于when-let ...
这不是我所期望的.If-let可以尝试所有绑定并在一个失败时中断并评估else表达式.
同样的抱怨可以在clojuredocs的评论中找到.我在这里找到了一个并不真正满足的答案,因为海报似乎有一个等同于嵌套的if-let-structure的想法.
有什么理由限制*-let宏的绑定?
更新:由于似乎不清楚,我对if-let的期望是:
在我的中间件中,我正在检查:session用户是否登录的值.
如果:session设置了值,它的效果很好.虽然,我不知道检查是否:session绑定的最佳方法是什么.
(defn logged-in-verify
[ring-handler]
(fn new-ring-handler
[request]
;;verify that the scrypt hash of email and timestamp matches.
(let [session (:session request)
email (:ph-auth-email session)
token (:ph-auth-token session)
timestamp (:ph-auth-timestamp session)]
(if (scryptgen/check (str email timestamp) token)
(do
;; return response from wrapped handler
(ring-handler request))
;; return error response
{:status 400, :body "Please sign in."}))))
Run Code Online (Sandbox Code Playgroud)
由于我不检查是否:session绑定,因此使用此中间件的内容会返回,NullPointerException如果它未设置.最好的方法是什么?