【问题标题】:How do I see the methods associated with an object in Clojure?如何在 Clojure 中查看与对象关联的方法?
【发布时间】:2011-11-02 19:22:11
【问题描述】:

我在 Clojure 中使用什么函数来查看 Java 对象的方法?

user=> (some-function some-java-object)
... lots of methods ...

【问题讨论】:

    标签: java methods clojure


    【解决方案1】:

    从 1.3 版开始,Clojure 与 clojure.reflect 命名空间捆绑在一起。函数reflect 特别可用于显示对象的所有方法(和其他信息)。使用起来不如show方便。另一方面,它更通用,使用reflect 作为构建块很容易编写自己的show 版本。

    例如,如果您想查看返回 String 的 String 的所有方法:

    user=> (use 'clojure.reflect)
    user=> (use 'clojure.pprint)
    
    user=> (->> (reflect "some object") 
                :members 
                (filter #(= (:return-type %) 'java.lang.String))
                (map #(select-keys % [:name :parameter-types])) 
                print-table)
    

    【讨论】:

    • 这是否适用于 v1.2.1(如果我向 project.clj 文件添加依赖项)?
    【解决方案2】:

    使用 java 反射。

    (.getClass myObject)
    

    为您提供课程。要获取方法,

    (.getMethods (.getClass myObject))
    

    这为您提供了一系列方法。您可以将其视为一个序列;我可能会把它放到一个向量中,所以:

    (vec (.getMethods (.getClass myObject)))
    

    【讨论】:

      【解决方案3】:
      user=> (map #(.getName %) (-> "foo" class .getMethods))
      
      ("equals" "toString" "hashCode" "compareTo" "compareTo" "indexOf" "indexOf" "indexOf" "indexOf" "valueOf" "valueOf" "valueOf" "valueOf" "valueOf" "valueOf" "valueOf" "valueOf" "valueOf" "length" "isEmpty" "charAt" "codePointAt" "codePointBefore" "codePointCount" "offsetByCodePoints" "getChars" "getBytes" "getBytes" "getBytes" "getBytes" "contentEquals" "contentEquals" "equalsIgnoreCase" "compareToIgnoreCase" "regionMatches" "regionMatches" "startsWith" "startsWith" "endsWith" "lastIndexOf" "lastIndexOf" "lastIndexOf" "lastIndexOf" "substring" "substring" "subSequence" "concat" "replace" "replace" "matches" "contains" "replaceFirst" "replaceAll" "split" "split" "toLowerCase" "toLowerCase" "toUpperCase" "toUpperCase" "trim" "toCharArray" "format" "format" "copyValueOf" "copyValueOf" "intern" "wait" "wait" "wait" "getClass" "notify" "notifyAll")
      

      用你的对象替换“foo”。

      【讨论】:

      • Clojure 1.10 添加了一个新的 datafy 函数。它似乎很好地反射。
      【解决方案4】:

      您曾经可以使用 show 来处理这类事情(例如,使用 clojure 1.2.0、clojure-contrib 1.2.0)。

      (ns test.core
        (:use [ clojure.contrib.repl-utils :only [show]]))
      

      来自 REPL

      (show Integer)
      

      成功

      ===  public final java.lang.Integer  ===
      static MAX_VALUE : int 
      static MIN_VALUE : int
      ... 
      

      奇怪的是,我用 clojure 1.3.0 /clojure-contrib 1.2.0 尝试了这个,但没有成功。 doc 似乎也坏了。

      【讨论】:

      • 在 1.2.0 中你包含/使用了什么来获得这个?是核心吗?
      • @Arthur 它在 clojure.contrib.repl-utils 中。我在上面添加了命名空间宏以进行说明。
      • 我做了更多的挖掘工作。 Clojure 正在从单一的 clojure.contrib 迁移到更模块化的库。 doc 宏现在位于 clojure.repl 中。不确定“显示”功能是否有新家。 (太糟糕了,它很有用)。从 Clojure 1.3 调用 repl-utils/show 似乎被破坏了。
      • clojure.contrib 现已弃用!
      【解决方案5】:

      IIRC 它不是内置的,但也很短--see this implementation

      (可能是现在。)

      【讨论】:

        【解决方案6】:

        您通常会列出这种方法,因为您正在寻找一种特定类型的方法……比如说类中的所有“get”类型的方法。以下是您可以为对象“obj”执行此操作的方法:

        (filter #(re-find #"get" %) (map #(.getName %) (.. obj getClass getMethods)))
        

        #"get" 是正则表达式对象,用于搜索名称中包含 get 的方法(根据您自己的需要进行自定义)。 map 表达式只是生成对象类中所有方法名称的序列; seq 被提供给匿名函数,它是传递给过滤器的第一个参数。

        【讨论】:

          猜你喜欢
          • 2013-04-23
          • 2012-02-08
          • 1970-01-01
          • 1970-01-01
          • 2014-11-24
          • 2015-09-04
          • 1970-01-01
          • 1970-01-01
          • 2014-05-23
          相关资源
          最近更新 更多