我需要匹配两种元组并从中生成地图。
两者都有一个关键字和一个字符串。可以有第三项(语言代码)。
[<key> <value>] ~> {:type <key> :value <value>}
[<key> <value> <lang>] ~> {:type <key> :value <value> :lang <lang>}
我只需要匹配那些关键字是:foo
or:bar
并决定我将使用clojure.core.match
:
(ns so.example
(:require
[clojure.core.match :refer [match]]))
(defn example-1 [ast]
(let [l10n-key #{:foo :bar}]
(match ast
[(k :guard l10n-key) v lang] {:type k :value v :lang lang}
[(k :guard l10n-key) v] {:type k :value v})))
(example-1 [:foo 10])
;=> {:type :foo, :value 10}
(example-1 [:bar 20 "en"])
;=> {:type :bar, :value 20, :lang "en"}
那行得通,但我想:guard l10n-key
在不同的子句中重用匹配模式。所以我想我可以使用一些语法引用和取消引用拼接:
(defn example-2 [ast]
(let [l10n-key-match [:guard #{:foo :bar}]]
(match ast
[`(k ~@l10n-key-match) v lang] {:type k :value v :lang lang}
[`(k ~@l10n-key-match) v] {:type k :value v})))
然而,defn
表达式崩溃:
Unexpected error (AssertionError) macroexpanding match at (form-init11111096422056977084.clj:3:5).
Invalid list syntax (clojure.core/concat (clojure.core/list (quote so.example/k)) l10n-key-match) in (clojure.core/seq (clojure.core/concat (clojure.core/list (quote so.example/k)) l10n-key-match)). Valid syntax: [[:default :guard] [:or :default] [:default :only] [:default :seq] [:default :when] [:default :as] [:default :<<] [:default :clojure.core.match/vector]]
我究竟做错了什么?