【问题标题】:Why am I getting a NullPointerException when executing macroexpand-1 on this Clojure macro?为什么在此 Clojure 宏上执行 macroexpand-1 时会出现 NullPointerException?
【发布时间】:2012-05-15 16:18:00
【问题描述】:

我正在学习 Clojure 宏,当我尝试在此宏上使用 macroexpand-1 时遇到 NullPointerException:

(def config {:ns 'bulbs.neo4jserver.client, 
             :root-uri "http://localhost:7474/db/data/"})
(def data {:name "James"})

(defmacro create
  [config data]
  `(~(ns-resolve (:ns config) 'create-vertex) config data))

(macroexpand-1 '(create config data))

尝试编译返回:

 Unknown location:
   error: java.lang.NullPointerException

 Compilation failed.

但是评估宏的主体...

`(~(ns-resolve (:ns config) 'create-vertex) config data)

...返回这个...

(#'bulbs.neo4jserver.client/create-vertex bulbs.vertices/config bulbs.vertices/data)

...这就是我想要的。

更新:如果我手动将(:ns config) 替换为'bulbs.neo4jserver.client,那么错误就会消失——你如何让(:ns config) 玩得更好?

【问题讨论】:

    标签: macros clojure


    【解决方案1】:

    您正在尝试混合使用宏扩展时间和运行时信息。本地“config”不包含#'config var的内容,而是符号'config。

    如果您查看完整的堆栈跟踪,而不仅仅是错误消息,您会看到 ns-resolve 被传递了一个 nil:

    user=> (pst)
    NullPointerException 
            java.util.concurrent.ConcurrentHashMap.get (ConcurrentHashMap.java:796)
            clojure.lang.Namespace.find (Namespace.java:188)
            clojure.core/find-ns (core.clj:3657)
            clojure.core/the-ns (core.clj:3689)
            clojure.core/ns-resolve (core.clj:3879)
            clojure.core/ns-resolve (core.clj:3876)
            clj.core/create (NO_SOURCE_FILE:7)
    

    一旦你理解了以下内容,你就会明白你原来的问题:

    user=> (def bar [1 2 3])
    user=> (defmacro foo [x] [(class x) (pr-str x)])
    user=> (foo (get bar 2))
    [clojure.lang.PersistentList "(get bar 2)"]
    

    【讨论】:

      【解决方案2】:

      为什么这是一个宏?在这种情况下,似乎可以使用正常的功能。

      请记住,config 绑定到您输入的文字值,所以如果您这样做了

      (def c {:ns 'foo})  
      (create c 1)
      

      config 将只是'c,而不是c 在运行时引用的映射。

      【讨论】:

        猜你喜欢
        • 2016-08-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-26
        • 1970-01-01
        • 2020-05-08
        • 1970-01-01
        相关资源
        最近更新 更多