<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # [X分鐘速成Y](http://learnxinyminutes.com/) ## 其中 Y=clojure macros 源代碼下載:?[learnclojuremacros-zh.clj](http://learnxinyminutes.com/docs/files/learnclojuremacros-zh.clj) 和所有Lisp一樣,Clojure內在的[同構性](https://en.wikipedia.org/wiki/Homoiconic)使得你可以窮盡語言的特性,編寫生成代碼的子過程——“宏”。宏是一種按需調制語言的強大方式。 小心!可以用函數完成的事用宏去實現可不是什么好事。你應該僅在需要控制參數是否或者何時eval的時候使用宏。 你應該熟悉Clojure.確保你了解[Y分鐘學Clojure](http://learnxinyminutes.com/docs/zh-cn/clojure-cn/)中的所有內容。 ~~~ ;; 使用defmacro定義宏。宏應該輸出一個可以作為clojure代碼演算的列表。 ;; ;; 以下宏的效果和直接寫(reverse "Hello World")一致。 (defmacro my-first-macro [] (list reverse "Hello World")) ;; 使用macroexpand或macroexpand-1查看宏的結果。 ;; ;; 注意,調用需要引用。 (macroexpand '(my-first-macro)) ;; -> (#<core$reverse clojure.core$reverse@xxxxxxxx> "Hello World") ;; 你可以直接eval macroexpand的結果 (eval (macroexpand '(my-first-macro))) ; -> (\d \l \o \r \W \space \o \l \l \e \H) ;; 不過一般使用以下形式,更簡短,更像函數: (my-first-macro) ; -> (\d \l \o \r \W \space \o \l \l \e \H) ;; 創建宏的時候可以使用更簡短的引用形式來創建列表 (defmacro my-first-quoted-macro [] '(reverse "Hello World")) (macroexpand '(my-first-quoted-macro)) ;; -> (reverse "Hello World") ;; 注意reverse不再是一個函數對象,而是一個符號。 ;; 宏可以傳入參數。 (defmacro inc2 [arg] (list + 2 arg)) (inc2 2) ; -> 4 ;; 不過,如果你嘗試配合使用引用列表,會導致錯誤, ;; 因為參數也會被引用。 ;; 為了避免這個問題,clojure提供了引用宏的另一種方式:` ;; 在`之內,你可以使用~獲得外圈作用域的變量。 (defmacro inc2-quoted [arg] `(+ 2 ~arg)) (inc2-quoted 2) ;; 你可以使用通常的析構參數。用~@展開列表中的變量。 (defmacro unless [arg & body] `(if (not ~arg) (do ~@body))) ; 別忘了 do! (macroexpand '(unless true (reverse "Hello World"))) ;; -> ;; (if (clojure.core/not true) (do (reverse "Hello World"))) ;; 當第一個參數為假時,(unless)會演算、返回主體。 ;; 否則返回nil。 (unless true "Hello") ; -> nil (unless false "Hello") ; -> "Hello" ;; 需要小心,宏會搞亂你的變量 (defmacro define-x [] '(do (def x 2) (list x))) (def x 4) (define-x) ; -> (2) (list x) ; -> (2) ;; 使用gensym來獲得獨有的標識符 (gensym 'x) ; -> x1281 (or some such thing) (defmacro define-x-safely [] (let [sym (gensym 'x)] `(do (def ~sym 2) (list ~sym)))) (def x 4) (define-x-safely) ; -> (2) (list x) ; -> (4) ;; 你可以在 ` 中使用 # 為每個符號自動生成gensym (defmacro define-x-hygenically [] `(do (def x# 2) (list x#))) (def x 4) (define-x-hygenically) ; -> (2) (list x) ; -> (4) ;; 通常會配合宏使用幫助函數。 ;; 讓我們創建一些幫助函數來支持(無聊的)算術語法: (declare inline-2-helper) (defn clean-arg [arg] (if (seq? arg) (inline-2-helper arg) arg)) (defn apply-arg "Given args [x (+ y)], return (+ x y)" [val [op arg]] (list op val (clean-arg arg))) (defn inline-2-helper [[arg1 & ops-and-args]] (let [ops (partition 2 ops-and-args)] (reduce apply-arg (clean-arg arg1) ops))) ;; 在創建宏前,我們可以先測試 (inline-2-helper '(a + (b - 2) - (c * 5))) ; -> (- (+ a (- b 2)) (* c 5)) ; 然而,如果我們希望它在編譯期執行,就需要創建宏 (defmacro inline-2 [form] (inline-2-helper form))) (macroexpand '(inline-2 (1 + (3 / 2) - (1 / 2) + 1))) ; -> (+ (- (+ 1 (/ 3 2)) (/ 1 2)) 1) (inline-2 (1 + (3 / 2) - (1 / 2) + 1)) ; -> 3 (事實上,結果是3N, 因為數字被轉化為帶/的有理分數) ~~~ ## 擴展閱讀 [Clojure for the Brave and True](http://www.braveclojure.com/)系列的編寫宏 http://www.braveclojure.com/writing-macros/ 官方文檔 http://clojure.org/macros 何時使用宏? http://dunsmor.com/lisp/onlisp/onlisp_12.html
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看