【问题标题】:How do I pass a static method to comp in clojure?如何将静态方法传递给clojure中的comp?
【发布时间】:2011-01-13 14:40:19
【问题描述】:

好像我在访问 Integer.parseInt 时遇到问题。我可以像这样正常访问它:

user=> (Integer/parseInt "123")
123

但是如果我把它放在comp中,我会得到一个错误:

user=> (def vect-to-int (comp Integer/parseInt (partial apply str)))
java.lang.Exception: Unable to find static field: parseInt in class java.lang.Integer (NO_SOURCE_FILE:3)

在我看来,它应该在寻找方法时试图在 Integer 上找到一个字段。我怎样才能像这样使用Integer.parseInt?有没有更好的方法将字符向量转换为int?

【问题讨论】:

    标签: string vector clojure integer


    【解决方案1】:

    Clojure 函数是 java 方法,但 java 方法不是 clojure 函数 例如 Clojure 函数具有元数据等。如果您想使用调用 Clojure 函数的 java 方法,那么您有两种选择来包装它,memfn 和 fun or #( ) memfn 是一个过时的函数,它将 java 方法包装在 clojure 函数中(它很好知道它存在,即使它不经常使用)。包装 java 方法的普遍接受的方式是:

    #(. instance method arg1 argN)  
    

    或用于静态方法

    #(Class/MethodName arg1 argN)
    

    【讨论】:

    • 我猜第一行并不完全正确,尽管它确实说明了重点:)
    • 我认为你的意思是 fn 而不是 fun 吗?
    【解决方案2】:
    (def vec-to-int (comp #(Integer/parseInt %) (partial apply str)))
    

    或者

    (def vec-to-int #(Integer/parseInt (apply str %)))
    

    partial 和 comp 在 Clojure 中通常不像使用 #() 来创建匿名 fn 那样简洁。我个人会这样写:

    (defn vec-to-int [x] (Integer/parseInt (apply str x)))
    

    您可以使用普通的def 来做到这一点,但是使用def 而不是defn 会得到什么,真的吗?使用def 掩盖了您正在定义一个函数的事实。 defn 还为您设置了 def 没有的其他元数据(参数列表)。

    无论如何,这是一种更通用的方式来做你正在做的事情:

    (def vec-to-int #(bigint (apply str %)))
    

    还有更笼统的:

    (def vec-to-int #(read-string (apply str %)))
    

    取决于您是否希望能够处理整数以外的事情。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多