Clojure 中的解构论证

Destructuring argument in Clojure

新手在这里享受 Clojure 很多。所以,我有一个 HTTP 路由:

 (POST   "/login"    request   (post-login request))

这里,"request"是一张地图,里面有很多http的东西。 "post-login" 函数:

(defn post-login
  ;; Login into the app
  [{{email "email" password "password"} :form-params session :session :as req}]
    (let [user (modusers/get-user-by-email-and-password email password)]
     ;; If authenticated
     (if-not (nil? (:user user))
      (do
       (assoc (response/found "/")
         :session (assoc session :identity (:user user)) :flash "Bitte schön!"))
       (assoc (response/found "/login") :flash "Etwas stimmt nicht mit deinem Zugriffsprozess"))))

但我不明白 "request" 是如何解构的。 "email" 和 "password" 现在如何在函数内部可用?以及“:as req”是什么意思?这个 "technique" 有名字吗?

如果从评论中仍然不清楚,这里有一个快速的答案:

您的 post-login 函数接收一个参数,该参数是表示 HTTP 请求的映射。在特殊的 :as 关键字的帮助下,此参数存储在 req 中。 所以(defn post-login [req] ...)(defn post-login [{:as req}] ...)是完全一样的。

地图解构的一种(一种)方式是在右侧提供一个地图键,在左侧提供它应该绑定的东西,例如[{form-params :form-params :as req}]。现在 req 映射中的 :form-params 键将绑定到函数体内可用的 form-params 符号。

当您进行 "nested" 解构时,事情会变得更有趣。在您的情况下, [{{email "email" password "password"} :form-params :as req} 仅意味着请求中的 :form-params 键将绑定到 {email "email" password "password"} ,这又是一个解构本身。最终,:form-params 中的 "email" 键将绑定到 email 符号,password 也是如此。 和以前一样,如果您需要访问整个请求(而不仅仅是其中的一些参数),您可以通过 :as.

获得。

注意:您可以使用另一种语法(一种快捷方式): [{{:strs [email password]} :form-params session :session :as req}]