我有一堆函数可以映射到外部系统定义的某些代码:
(defn translate-from-ib-size-tick-field-code [val]
(condp = val
0 :bid-size
3 :ask-size
5 :last-size
8 :volume))
(defn translate-to-ib-size-tick-field-code [val]
(condp = val
:bid-size 0
:ask-size 3
:last-size 5
:volume 8))
Run Code Online (Sandbox Code Playgroud)
我想制作一个宏来删除重复:
#_ (translation-table size-tick-field-code
{:bid-size 0
:ask-size 3
:last-size 5
:volume 8})
Run Code Online (Sandbox Code Playgroud)
我开始像这样的宏:
(defmacro translation-table [name & vals]
`(defn ~(symbol (str "translate-to-ib-" name)) [val#]
(get ~@vals val#)))
Run Code Online (Sandbox Code Playgroud)
结果函数体似乎正确,但函数名称错误:
re-actor.conversions> (macroexpand `(translation-table monkey {:a 1 :b 2}))
(def translate-to-ib-re-actor.conversions/monkey
(.withMeta (clojure.core/fn translate-to-ib-re-actor.conversions/monkey
([val__10589__auto__]
(clojure.core/get {:a 1, :b 2} val__10589__auto__))) (.meta ...
Run Code Online (Sandbox Code Playgroud)
事实证明,我希望"translate-to-ib-"作为函数名称的一部分出现,而不是名称空间的前缀.
我怎么能用clojure宏做这个?如果我只是做错了并且由于某种原因不应该使用宏,请告诉我,但我也想知道如何创建这样的函数名称来提高我对clojure和宏的理解.谢谢!
宏观问题有两个方面:
1)在引用传递给的表单时,您正在使用反引号macroexpand,该命名空间限定符号:
`(translation-table monkey {:a 1 :b 2})
=> (foo.bar/translation-table foo.bar/monkey {:a 1, :b 2})
Run Code Online (Sandbox Code Playgroud)
foo.bar你在哪里的名字空间.
2)您正在defn使用符号构造项目的名称name,当它符合名称空间时,将字符串化为"foo.bar/monkey".这是一个可行的版本:
(defmacro translation-table [tname & vals]
`(defn ~(symbol (str "translate-to-ib-" (name tname))) [val#]
(get ~@vals val#)))
Run Code Online (Sandbox Code Playgroud)
请注意,我们tname使用该name函数获取了没有命名空间部分的名称.
至于宏是否是正确的解决方案,可能不是:-)对于这样的简单案例,我可能只使用地图:
(def translate-from-ib-size-tick-field-code
{0 :bid-size
3 :ask-size
5 :last-size
8 :volume})
;; swap keys & vals
(def translate-to-ib-size-tick-field-code
(zipmap (vals translate-from-ib-size-tick-field-code)
(keys translate-from-ib-size-tick-field-code)))
(translate-from-ib-size-tick-field-code 0)
=> :bid-size
(translate-to-ib-size-tick-field-code :bid-size)
=> 0
Run Code Online (Sandbox Code Playgroud)
如果速度至关重要,请查看case.
| 归档时间: |
|
| 查看次数: |
1033 次 |
| 最近记录: |