簡體   English   中英

宏字符串插值/如何在字符串中取消引用?

[英]Macro string Interpolation / How to unquote inside string?

我有一個像這樣的宏:

(defmacro test [x] `"~x")

運行后展開如下:

=> (test abc)
'~x'

為什么它不擴展為'abc'

在字符串中取消引號的正確方法是什么?

我很困惑為什么你期望這會起作用,我不清楚你想要什么。 ~在你的例子中是一個字符串文字,所以它是一個普通的字符串字符,而不是~運算符,就像((fn [x] "x") 5)返回"x"而不是"5"一樣。

如果您想對您傳遞給宏的 model 進行字符串化,請使用str ,如下所示:

hy 1.0a1+114.g2abb33b1 using CPython(default) 3.8.6 on Linux
=> (defmacro test [x] (str x))
<function test at 0x7fe0476144c0>
=> (test abc)
"abc"

我認為這里有一個更普遍的問題:如何在宏擴展時使用字符串插值?

答案是要記住 unquote 前綴~可以應用於任何形式,而不僅僅是簡單的符號,它只是unquote的簡寫。

所以你可以只使用一個 f 字符串,並取消引用 f 字符串。 使用原始示例:

(defmacro test [x]
  (quasiquote (unquote f"{x}")))

或者使用速記前綴符號:

(defmacro test [x]
  `~f"{x}")

~f"{module}..."是 `(unquote f"{module}...") 的有效簡寫。

作為將任意 forms 與~一起使用的另一個示例,您可以使用str.format而不是 f 字符串:

(defmacro test [x]
  `~(.format "{}" x))

作為一個真實世界的例子,這是我今天寫的一個宏:

(import sys
  typing [NoReturn])

(defn ^NoReturn die [^int status ^str message]
  (print message :file sys.stderr)
  (sys.exit status))

(defmacro try-import [module]
  `(try
     (import ~module)
     (except [ImportError]
       (die 1 ~f"{module} is not available, exiting."))))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM