web – 何时使用Var而不是函数?

前端之家收集整理的这篇文章主要介绍了web – 何时使用Var而不是函数?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在浏览clojure Web开发书,它告诉我传递处理程序(定义为bellow)var对象而不是函数本身,因为函数将动态更改(这就是wrap-reload所做的).

这本书说:

“请注意,我们必须从处理程序创建一个var才能使用此中间件
上班.这是确保包含当前的Var对象所必需的
处理函数返回.如果我们使用处理程序而不是应用程序
只能看到功能的原始值,并且不会反映出变化.“
我真的不明白这意味着什么,变量类似于c指针?

(ns ring-app.core
  (:require [ring.adapter.jetty :as jetty]
            [ring.util.response :as response]
            [ring.middleware.reload :refer [wrap-reload]]))

(defn handler [request]
  (response/response
   (str "<html>/<body> your IP is: " (:remote-addr request)
        "</body></html>")))

(defn wrap-nocache [handler]
  (fn [request]
    (-> request
        handler
        (assoc-in [:headers "Pragma"] "no-cache"))))

这是处理程序调用

(defn -main []
  (jetty/run-jetty
   (wrap-reload (wrap-nocache  (var handler)))
   {:port 3001
    :join? false}))

解决方法

是的,var类似于C指针.这个记录很少.

假设你定义fred如下:

(defn fred [x] (+ x 1))

这里实际上有三件事.首先,弗雷德是一个象征.符号fred(无引号)与关键字:fred(由leading:char标记)和字符串“fred”(两端用双引号标记)之间存在差异.对于Clojure,每个人都由4个字符组成;即,关键字的冒号和字符串的双引号都不包含在它们的长度或组成中:

> (name 'fred)
"fred"
> (name :fred)
"fred"
> (name "fred")
"fred"

唯一的区别是如何解释它们.字符串用于表示任何类型的用户数据.关键字意味着以可读的形式表示程序的控制信息(与“幻数”相反,例如1 =左,2 =右,我们只使用关键字:左和右.

符号意味着指向事物,就像在Java或C中一样.如果我们说

(let [x 1
      y (+ x 1) ]
  (println y))
;=> 2

然后x指向值1,y指向值2,我们看到打印结果.

(def …)表单引入了一个不可见的第三个元素var.所以,如果我们说

(def wilma 3)

我们现在要考虑3个对象. wilma是一个符号,它指向一个var,而var又指向值3.当我们的程序遇到符号wilma时,会对其进行求值以查找var.同样,var被评估为产生值3.所以它就像是C中指针的2级间接.因为符号和var都是“自动评估”,所以这是自动且不可见的,你不会不得不考虑var(事实上,大多数人并不真正意识到隐形中间步骤甚至存在).

对于我们上面的函数fred,存在类似的情况,除了var指向匿名函数(fn [x](x 1))而不是像Wilma那样的值3.

我们可以将var的自动评估“短路”:

> (var wilma)
#'clj.core/wilma

要么

> #'wilma
#'clj.core/wilma

读者宏#'(pound-quote)是调用(var …)特殊形式的简写方式.请记住,像var这样的特殊形式是内置的编译器,如’if’或’def’,与常规函数不同. var特殊形式返回附加到符号wilma的var对象. clojure REPL使用相同的速记打印var对象,因此两个结果看起来都一样.

获得var对象后,将禁用自动评估:

> (println (var wilma))
#'clj.core/wilma

如果我们想要达到wilma指向的值,我们需要使用var-get:

> (var-get (var wilma))
3
> (var-get    #'wilma)
3

同样的事情适用于fred:

> (var-get #'fred)
#object[clj.core$fred 0x599adf07 "clj.core$fred@599adf07"]
> (var-get (var fred))
#object[clj.core$fred 0x599adf07 "clj.core$fred@599adf07"]

其中#object [clj.core $fred …]的东西是Clojure将函数对象表示为字符串的方式.

关于Web服务器,它可以通过var告诉?函数或其他函数,如果提供的值是处理函数或指向处理函数的var.

如果您键入以下内容

(jetty/run-jetty handler)

double auto-evaluation将产生处理函数对象,该对象被传递给run-jetty.相反,如果您输入:

(jetty/run-jetty (var handler))

那么指向处理函数对象的var将被传递给run-jetty.然后,run-jetty将必须使用if语句或等效语句来确定它已接收到的内容,如果已收到var而不是函数,则调用(var-get …).因此,每次通过(var-get …)将返回var当前指向的对象.因此,var的作用类似于C中的全局指针,或者Java中的全局“引用”变量.

如果将函数对象传递给run-jetty,它会将“本地指针”保存到函数对象中,并且外部世界无法更改本地指针所引用的内容.

您可以在此处找到更多详细信息

> http://clojure.org/reference/evaluation
> http://clojure.org/reference/vars

猜你在找的HTML相关文章