【问题标题】:How to defn a function from string in Clojure?如何从 Clojure 中的字符串定义函数?
【发布时间】:2010-10-15 07:10:30
【问题描述】:

我想这样做(在 REPL 或任何地方)

(defn (symbol "print-string") [k] (println k))

然后就可以了

(print-string "lol")

或者,如果有任何其他方法可以从宏中的自定义字符串创建 defn,您能否将我推向正确的方向?

【问题讨论】:

    标签: function clojure metaprogramming eval defn


    【解决方案1】:
    (defmacro defn-with-str [string args & body]
     `(defn ~(symbol string) ~args ~@body))
    
    (defn-with-str "print-string" [k] (println k))
    
    (print-string "lol")
    

    【讨论】:

    • 1. args 前面的 ~ 是什么? 2. body前面的~@是什么?
    • @Belun 1. ~ = 取消引用 2.~@ = 展开序列
    • 为什么如果我这样做 (defn defns [] (doall (map (fn [s] (defn-with-str s [k] (println k))) ["print-string "]))) 我得到一个名为 's' 的 fn ?
    • @Hendekagon 宏不是常规函数
    【解决方案2】:

    我更喜欢 dnolen 的回答,但你也可以这样做:

    (defn #=(symbol "print-string") [k] (println k))

    #=() 在读取时进行评估。我不知道 Clojure 的一个特性有多稳定,我不会指望它在未来不改变。宏就是我的做法。

    【讨论】:

      【解决方案3】:

      dnolen 的解决方案在宏扩展时有效,Brian Carper 在读取时有效。现在,这是运行时的一个:

      (intern *ns* (symbol "a") (fn [k] (println k)))
      

      【讨论】:

      • 酷不知道这一点。需要注意的是,var a 将丢失使用 defn 获得的函数元数据。
      【解决方案4】:

      仅供参考 - dnolen 的答案仅适用于文字字符串,不适用于 def'd 或 let'd 变量中的字符串。

      (defmacro defn-with-str [字符串参数和正文] `(defn ~(symbol string) ~args ~@body))

      (def hisym "hi") (defn-with-str hisym [] (println "hi"))

      您现在有一个名为“hisym”的函数

      (hi) -> java.lang.Exception: Unable to resolve symbol: hi in this context (NO_SOURCE_FILE:6) (hisym) -> 打印“hi”

      为避免这种情况,请评估宏中的函数名称字符串

      (defmacro defn-with-str [string args & body]
      `(defn ~(symbol (eval string)) ~args ~@body))

      【讨论】:

        猜你喜欢
        • 2011-08-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-27
        • 1970-01-01
        相关资源
        最近更新 更多