宏字符串插值/如何在字符串中取消引用?
Macro string Interpolation / How to unquote inside string?
我有一个像这样的宏:
(defmacro test [x] `"~x")
在 运行 之后扩展为以下内容:
=> (test abc)
'~x'
为什么不扩展到 'abc'
?
在字符串中取消引号的正确方法是什么?
我不明白你为什么希望它起作用,我不清楚你想要什么。 ~
在你的例子中是一个字符串文字,所以它是一个普通的字符串字符,而不是 ~
运算符,与 ((fn [x] "x") 5)
returns "x"
和不是 "5"
.
如果您想将传递给宏的模型字符串化,请使用 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"
我认为这里有一个更普遍的问题:如何在 macro-expansion 时使用字符串插值?
答案是要记住,反引号前缀 ~
可以应用于 任何形式 ,而不仅仅是空符号,它只是 shorthand unquote
.
因此您可以只使用 f-string,并取消引用 f-string。使用原始示例:
(defmacro test [x]
(quasiquote (unquote f"{x}")))
或使用shorthand前缀符号:
(defmacro test [x]
`~f"{x}")
~f"{module} ..."
对 `(unquote f"{module} ...") 有效 shorthand。
作为使用 ~
的任意形式的另一个示例,您可以使用 str.format
而不是 f-string:
(defmacro test [x]
`~(.format "{}" x))
作为一个real-world例子,这是我今天写的一个宏:
(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."))))
我有一个像这样的宏:
(defmacro test [x] `"~x")
在 运行 之后扩展为以下内容:
=> (test abc)
'~x'
为什么不扩展到 'abc'
?
在字符串中取消引号的正确方法是什么?
我不明白你为什么希望它起作用,我不清楚你想要什么。 ~
在你的例子中是一个字符串文字,所以它是一个普通的字符串字符,而不是 ~
运算符,与 ((fn [x] "x") 5)
returns "x"
和不是 "5"
.
如果您想将传递给宏的模型字符串化,请使用 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"
我认为这里有一个更普遍的问题:如何在 macro-expansion 时使用字符串插值?
答案是要记住,反引号前缀 ~
可以应用于 任何形式 ,而不仅仅是空符号,它只是 shorthand unquote
.
因此您可以只使用 f-string,并取消引用 f-string。使用原始示例:
(defmacro test [x]
(quasiquote (unquote f"{x}")))
或使用shorthand前缀符号:
(defmacro test [x]
`~f"{x}")
~f"{module} ..."
对 `(unquote f"{module} ...") 有效 shorthand。
作为使用 ~
的任意形式的另一个示例,您可以使用 str.format
而不是 f-string:
(defmacro test [x]
`~(.format "{}" x))
作为一个real-world例子,这是我今天写的一个宏:
(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."))))