gpt4 book ai didi

clojure - 为什么 compojure 路由定义为宏?

转载 作者:行者123 更新时间:2023-12-04 14:39:50 37 4
gpt4 key购买 nike

例如 Luminus 网站 states

Compojure route definitions are just functions that accept request maps and return response maps...

(GET "/" [] "Show something")
...


但是compojure路线是 不是 职能
(defmacro GET "Generate a `GET` route."
[path args & body]
(compile-route :get path args body))

可以使用功能 make-route返回一个函数,但不允许解构。因此,作为函数,您不能使用 compojure 的特殊语法进行解构(即向量),但这是否会阻止任何形式的解构?来自给他们的宏是否提高了性能?
(make-route :get "/some_path" some_handler)

不能使用宏包装器将破坏语法传递给函数吗?

最佳答案

使用宏的原因之一是用户可以编写函数和符号名称而无需引用所有内容。以这个例子from the Clojure Cookbook :

; Routing
(defroutes main-routes
(GET "/" [] (index))
(GET "/en/" [] (index))
(GET "/fr/" [] (index-fr))
(GET "/:greeting/" [greeting] (view greeting)))

所有的 index*符号,加号 viewgreeting如果 GET,则必须引用是一个函数:
; Routing
(defroutes main-routes
(GET "/" [] '(index))
(GET "/en/" [] '(index))
(GET "/fr/" [] '(index-fr))
(GET "/:greeting/" '[greeting] '(view greeting)))

由于函数参数在调用函数之前被求值, (index)等人将在阅读表格后立即进行评估。另外, greeting arg 将在每个 HTTP 请求上发生变化,因此显然无法提前知道。

宏还负责处理常规函数(通常)无法实现的所有解构魔法。

经常令人困惑(并且没有向初学者很好地解释)的事情是这样的一行:
(GET "/:greeting/" [greeting] (view greeting))

不是正常的“Clojure 代码”。相反,它是 GET 的一种速记(准确地说是领域特定语言或 DSL)。宏将摄取并用作有关如何生成“合法”Clojure 代码的说明。 DSL 通常比最终生成的代码更短、更简单、更方便人类,正如 Clojure 比 Clojure 编译器生成的 Java 字节码或最终的机器汇编语言代码更短、更简单、更方便由 JVM 生成。

简而言之,每个宏都是一个“预编译器”,它将 DSL 转换为普通的 Clojure,然后由 Clojure 编译器摄取以生成 Java 字节码。

话虽如此,它 可以 重新安排将所有的宏魔法放入 defroutes宏使 GET符号既不是函数也不是宏,而只是一种标记,如 :get实现中的关键字。作为用户,这些类型的实现细节通常无关紧要。

更新

最好仅在某个函数不起作用或非常笨拙时才使用宏。决定因素通常是人们是否想使用裸(未加引号)符号,但不提前评估它们。核心 Clojure 本身对许多其他语言中“内置”的结构使用宏,包括 defn , for , and , or , when , 和别的。

还要注意一个宏 不能 做一些函数可以做的事情,例如作为高阶函数的参数,如 filter .

总之,一个函数定义了一个 行为 .宏定义了 语言扩展 .

关于clojure - 为什么 compojure 路由定义为宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44683971/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com