是否可以使用lisp的宏來進行字符串插值?反引號字符串插值
舉例來說,我可以做這樣的宏:
(defmacro test (a) `",a")
所以這(測試ABC)返回 「ABC」 作爲一個字符串?我可以通過引用它並將該引號轉換爲字符串來作弊,但這對於「9:00」(不帶雙引號)的參數不起作用。
是否可以使用lisp的宏來進行字符串插值?反引號字符串插值
舉例來說,我可以做這樣的宏:
(defmacro test (a) `",a")
所以這(測試ABC)返回 「ABC」 作爲一個字符串?我可以通過引用它並將該引號轉換爲字符串來作弊,但這對於「9:00」(不帶雙引號)的參數不起作用。
Lisp的宏在參數上操作該已經被lisp的讀者讀過。因爲宏不能改變它讀取參數的方式,並且如果你傳遞一個參數,當你嘗試讀取它時會報錯,例如9:00
在(test 9:00)
中,讀取器在宏開始運行之前發出錯誤信號。
閱讀器也是可定製的。不能以一種直接的方式讀取9:00
作爲"9:00"
,但例如,您可以編寫一個簡短的讀取器宏,其讀取@9:00
爲"9:00"
或作爲日期對象。
編輯:事情是這樣的:
(defvar *arguments-rt* (copy-readtable()))
(defun timestring-reader (stream char &optional count)
(declare (ignore char count))
(with-output-to-string (s)
(loop repeat 4 do (write-char (read-char stream) s))))
(set-macro-character #\@ #'timestring-reader() *arguments-rt*)
(let ((*readtable* *arguments-rt*))
(let ((args "dinner @9:00"))
(with-input-from-string (stream args)
(loop for arg = (read stream()())
while arg collect arg))))
-> (DINNER "9:00")
對於字符串插值,請參見format
。例如。 (format nil "~a" a)
做你想做的。在Practical Common Lisp有一些format recipes
quasiquote和unquote只適用於列表,而不是其他序列。
宏是代碼的轉換。它不是運行時發生的事情。例如。當你有像(my-macro x)
這樣的代碼,其中x
在運行時將是一個字符串,宏只能看到該符號。它不知道在擴展時它是什麼類型。
Backquoting,無論是在宏觀還是不行,不會做到這一點:
[1]> (defmacro test (a) `",a")
TEST
[2]> (test oh-no)
",a"
你可以做的是使用format
,如下:
[3]> (defun interp (name) (format nil "Hi, my name is ~A" name))
INTERP
[4]> (interp "Steve")
"Hi, my name is Steve"
嘗試['(符號名「一)'](http://clhs.lisp.se/Body/f_symb_2.htm)。 – Dan
@Dan:這對我的例子不起作用。 '9:00試圖尋找一個名爲「9」的包,它不存在。 – iHuman
@iHuman你需要逃避它。例如。 9:00或9:00。 – Sylwester