【问题标题】:How can I add a second parameter to a macro in Clojure?如何在 Clojure 的宏中添加第二个参数?
【发布时间】:2014-11-04 14:47:33
【问题描述】:

我有以下带有 1 个参数的 Clojure 包装宏:

(defmacro with-init-check
"Wraps the given statements with an init check."
[body]
`(if (initialized?)
  ~body
  (throw (IllegalStateException. "GeoIP db not initialized."))))

我想在其中添加ip-version,以便检查是否仅初始化了:IPv6:IPv4。但是,当我尝试这样做时,参数没有通过:

(defmacro with-init-check
  "Wraps the given statements with an init check."
  [ip-version body]
  `(if (initialized? ip-version)
    ~body
    (throw (IllegalStateException. "GeoIP db not initialized."))))

当我这样使用它时,我在“if-let [location...”行得到“no such var”:

(defn- lookup-location
  "Looks up IP location information."
  [ip ip-version]
  (with-init-check ip-version
    (if-let [location (get-location ip ip-version)]
  {:ip ip
   :countryCode (.countryCode location)
   :countryName (.countryName location)
   :region (.region location)
   :city (.city location)
   :postalCode (.postalCode location)
   :latitude (.latitude location)
   :longitude (.longitude location)
   :dma-code (.dma_code location)
   :area-code (.area_code location)
   :metro-code (.metro_code location)})))

如何将ip-version 传递给initialized? 函数?

【问题讨论】:

标签: macros clojure with-statement


【解决方案1】:

~取消引用:

(defmacro with-init-check
  "Wraps the given statements with an init check."
  [ip-version body]
  `(if (initialized? ~ip-version) ; unquoted with ~
     ~body
     (throw (IllegalStateException. "GeoIP db not initialized."))))

从您的文档字符串中推断,您可能还希望允许多表达式主体并在 do 表达式中取消引用拼接它们:

(defmacro with-init-check
  "Wraps the given statements with an init check."
  [ip-version & body] ; multi-expression bodies with &
  `(if (initialized? ~ip-version)
     (do ~@body) ; unquote-spliced with ~@
     (throw (IllegalStateException. "GeoIP db not initialized."))))

【讨论】:

    猜你喜欢
    • 2016-01-29
    • 2011-07-12
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 2021-12-28
    • 2011-10-21
    • 1970-01-01
    相关资源
    最近更新 更多