【问题标题】:Clojure: determine if a function existsClojure:判断一个函数是否存在
【发布时间】:2011-10-10 16:25:41
【问题描述】:

我如何知道作为字符串提供的函数名在当前上下文中是否可调用?类似:

(callable? "asdasd") ;; false
(callable? "filter") ;; true

谢谢

【问题讨论】:

  • 还要注意“可调用”这个词在这里被重载了。所有 Clojure 函数都是 java.util.concurrent.Callables。

标签: clojure lisp


【解决方案1】:

你正在寻找解决方案,

(resolve (symbol "asd"))

返回零

(resolve (symbol "filter"))

返回 #'clojure.core/filter

检查 var 是否为函数(感谢 @amalloy):

(-> s symbol resolve deref ifn?)

【讨论】:

  • 它返回你所说的,但我如何确定它是否可调用?
  • 你可以调用 (fn? (resolve (symbol "filter"))) - 我会推荐这个而不是我的回答
  • @JoostDiepenmaat:在这种情况下,(fn? (eval (symbol "filter"))) - resolve 返回类或 var,而不是带有 Fn 接口的东西(请参阅我的答案),因此将不起作用。
  • @ffriend,只需取消引用 var:(when-let [f (resolve (symbol "filter"))] (and (var? f) (fn? @f)))
  • 您可能根本不应该这样做,但完整的解决方案是(-> s symbol resolve deref ifn?)
【解决方案2】:

如果你需要这个,你可能做错了什么,但是......

(defn callable? 
  [s] 
  (let [obj (try (eval (symbol s)) (catch Exception e))]
  (and obj (fn? obj))))

【讨论】:

  • 没有。使用resolve 表示您可能做错了什么;使用eval 执行相同的任务肯定表明您做错了。
【解决方案3】:
(defn callable? [name]      
   (clojure.test/function? (symbol name)))

UPD. 我发现fn? 只检查接口Fn,并且不适用于已解析的符号。不过,clojure.test/function? 做了需要做的事情,所以我更新了一个示例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-02
    • 2023-01-28
    • 1970-01-01
    • 2011-08-17
    • 1970-01-01
    • 2013-10-02
    • 1970-01-01
    • 2011-05-24
    相关资源
    最近更新 更多