ELisp編程十三:宏二

來源:互聯網
上載者:User

為什麼分兩個步驟:先展開宏,再求值。

因為單單有一個宏定義(這裡稱macro body)是不能在編譯時間求值的,宏的參數還沒呢。宏的參數必須要等到編譯器看到宏調用代碼的時候才能知道。因此將宏參數傳遞給宏定義,然後展開宏再求值,是唯一能行的方法。

很好理解,這裡就像C++的一樣。

反引號(Backquote)`

最簡單的情況下,和‘功能相同,代表不要對一個list求值

     `(a list of (+ 2 3) elements)          ⇒ (a list of (+ 2 3) elements)     '(a list of (+ 2 3) elements)          ⇒ (a list of (+ 2 3) elements)

上面兩個運算式是等價的。

下面的宏

(defmacro inc (var)        (list 'setq var (list '1+ var)))

用反引號的簡化寫法是:

(defmacro inc2 (var)        `(setq ,var (1+ ,var)))

反引號的特殊在於如果在裡面的list中使用,號,會告訴編譯器如何展開該宏:

1.將,後面的求值,

2.用值來替換該處的原運算式

`(a list of ,(+ 2 3) elements)          ⇒ (a list of 5 elements)

這裡,(+2 3) 被求值成了5,5就作為一個元素加入到這個list中。

這種用法可以應用在定義宏的時候,請注意差別很大。

(defmacro t-becomes-nil (variable)       `(if (eq ,variable t)            (setq ,variable nil)))

(macroexpand '(t-becomes-nil foo))

這句宏調用展開後等價於:

(if (eq foo t) (setq foo nil))

如果將宏定義中的,去掉,等價於:

(if (eq varialbe t) (setq variable nil))

此處沒有求值。

`後面的運算式裡面可以用,@符號表示將一個list的值添加進來,比如:

(setq some-list '(2 3))          ⇒ (2 3)     `(1 ,@some-list 4 ,@some-list)          ⇒ (1 2 3 4 2 3)

可讀性大大加強,另一種可讀性差的寫法:

(cons 1 (append some-list '(4) some-list))          ⇒ (1 2 3 4 2 3)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.