<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 11, comments - 9, trackbacks - 0, articles - 0
      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    Clojure的變量和全局環(huán)境

    Posted on 2012-07-31 01:48 steven.cui 閱讀(1495) 評論(0)  編輯  收藏 所屬分類: clojure

    原文請參考,如有問題和歧義請指正,謝謝:)

    http://clojure.org/vars

    變量和全局環(huán)境

    Clojure是個很實(shí)用的語言,偶爾需要將維護(hù)和改變數(shù)據(jù)的值。她提供了4種不同的方式來操作變量:Vars, Refs, Agents, 和Atoms。Vars機(jī)制是是指向一個可改變的數(shù)據(jù)的位置,你可以為每個線程動態(tài)的綁定(制定一個新的存儲位置)一個新值。Vars可以初始化根綁定(不是必須的),綁定的值對于所有線程都是共享的,但卻別的線程就不能重新綁定。因此,要么Var可以為每個線程綁定值,要么使用根綁定。

    下面的special form def 創(chuàng)建了一個Var,如果Var不存在和沒有給初始化,var就是不綁定的(不允許創(chuàng)建非動態(tài)的Var,必須顯式指定根綁定):

    user=> (def x)
    #'user/x
    user=> x
    java.lang.IllegalStateException: Var user/x is unbound.

    為根值初始化(如果存在,就被再次綁定)

    user=> (def x 1)
    #'user/x
    user=> x
    1
     

    默認(rèn)情況下(定義的時候初始化了根綁定),Vars是靜態(tài)的(static),但是,建立動態(tài)Var的定義可以通過元數(shù)據(jù)標(biāo)記的方式,然后在線程用時通過binding來指定。

    user=> (def ^:dynamic x 1)

    user=> (def ^:dynamic y 1)

    user=> (+ x y)

    2

    user=> (binding [x 2 y 3]

             (+ x y))

    5

    user=> (+ x y)

    2

     

    binding被創(chuàng)建后其他線程是是不可見的。創(chuàng)建的binding可以被賦值,也就是在沒有離開調(diào)用堆棧之前可以被上下文訪問??梢栽谝粔K代碼之前設(shè)置matadata標(biāo)簽:dynamic來指定:

    user=> (def ^:dynamic x 1)

    #'user/x

    user=> (meta #'x)

    {:ns #<Namespace user>, :name x, :dynamic true, :line 30, :file "NO_SOURCE_PATH"}

    user=> (binding [x 2] (println x))

    2

    nil

    user=> x

    1

    user=>

     

    如果你想讓函數(shù)編譯為static的,并且指定返回值,可以看下面的例子(速度提升不少,關(guān)鍵的調(diào)用函數(shù)可以采用這種方式加速):

     (defn fib [n]   (if (<= n 1)

        1

        (+ (fib (dec n)) (fib (- n 2)))))

    #'user/fib

     (defn ^:static fib2 ^long [^long n]

      (if (<= n 1)

        1

        (+ (fib2 (dec n)) (fib2 (- n 2)))))

    #'user/fib2

    user=> (time (fib 38))

    "Elapsed time: 1831.113 msecs"

    63245986

    user=> (time (fib2 38))

    "Elapsed time: 328.715 msecs"

    63245986

    user=> (meta (var fib))

    {:arglists ([n]), :ns #<Namespace user>, :name fib, :line 1, :file "NO_SOURCE_PATH"}

    user=> (meta (var fib2))

    {:arglists ([n]), :ns #<Namespace user>, :name fib2, :static true, :line 4, :file "NO_SOURCE_PATH"}

    user=>

     

    在上下文中可能需要重定義靜態(tài)變量,從Clojure1.3開始提供with-redefswith-redefs-fn這兩個宏來修改。

    定義函數(shù)的defn也是Vars的存儲方式,也可以在運(yùn)行時被重定義。這也為aop編程帶來很多方便,例如:你可以封裝一個類似logging函數(shù)給調(diào)用的上下文或者或者線程。

     

    (set! var-symbol expr)

    將Vars指定為special form

    當(dāng)?shù)匾粋€操作符為symbol的時候,它必須是全局變量。當(dāng)前線程綁定的值就是后面的expr,也就是說必須是Thread-local的才可以,否則將會拋出一個使用set!來設(shè)定根綁定變量的錯誤。變量的表達(dá)式expr必須有返回值。

    注意,你不能賦值給一個函數(shù)的參數(shù)或者本地綁定,只能是java的字段Vars Refs和Agents,因?yàn)檫@些數(shù)據(jù)在Clojure里可不變的。

    使用set為java字段設(shè)置值,可以查看 Java Interop.

     

    Interning

    命名空間維護(hù)了每個Var對象的全局符號映射。如果使用def定義變量沒有在當(dāng)前的命名空間找到該符號,就創(chuàng)建一個,否則使用現(xiàn)有的。創(chuàng)建或者尋找的過程被稱作interning。這就意味著,除非Var對象取消映射,否則Var對象每次被查詢,所以請?jiān)谘h(huán)中千萬不要引用Var的全局變量,否則將非常慢,通過let或者binding讓全局變量取消映射來提高速度。命名空間在Evaluation中構(gòu)建了全局環(huán)境,編譯器也把所有free symbols當(dāng)做Vars來解析了。

    可以使用閱讀宏(Reader)#’來得到Var對象的內(nèi)部的值。

     

    Non-interned的類型的變量

    可以通過with-local-vars來創(chuàng)建non-interned類型的變量,在free symbol解析的時候?qū)⒉粫话l(fā)現(xiàn),這些值只能被手工的訪問,但是也可以用作當(dāng)前線程的變量。

    user=> (defn factorial [x]

             (with-local-vars [acc 1, cnt x]

               (while (> @cnt 0)

                 (var-set acc (* @acc @cnt))

                 (var-set cnt (dec @cnt)))

               @acc))

    #'user/factorial

    user=> (factorial 7)

    5040


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 久久久久久a亚洲欧洲aⅴ| 啦啦啦手机完整免费高清观看| 有码人妻在线免费看片| 久久亚洲欧美国产精品| 亚洲aⅴ无码专区在线观看 | 亚洲一区在线免费观看| 亚洲视频免费播放| 久久久久久精品免费看SSS| 久久久久av无码免费网| 免费三级毛片电影片| 在线成人a毛片免费播放| 在线观看免费亚洲| 免费人成在线观看视频播放 | 亚洲一区免费在线观看| 免费观看激色视频网站(性色)| AV无码免费永久在线观看| 永久免费av无码不卡在线观看| 午夜神器成在线人成在线人免费 | a毛片在线免费观看| 久久精品电影免费动漫| 18禁止看的免费污网站| 成人免费无码视频在线网站| 四虎成人精品一区二区免费网站 | 91精品国产免费| 91在线视频免费播放| 日韩精品免费一区二区三区| 亚洲精品国产va在线观看蜜芽| 亚洲精品成人片在线观看精品字幕| 亚洲精品自产拍在线观看动漫| 亚洲精品国产啊女成拍色拍| 中文字幕 亚洲 有码 在线 | 亚洲综合无码一区二区三区| 亚洲一区AV无码少妇电影| 老外毛片免费视频播放| 日本免费在线观看| 最近中文字幕mv手机免费高清| 亚洲精品国产va在线观看蜜芽| 久久青青成人亚洲精品| 亚洲欧洲AV无码专区| 久久久久久久国产免费看| 国内精品免费麻豆网站91麻豆|