#java #methods #clojure
#java #методы #clojure
Вопрос:
Какую функцию я использую в Clojure, чтобы увидеть методы объекта Java?
user=> (some-function some-java-object)
... lots of methods ...
Ответ №1:
Начиная с версии 1.3, Clojure поставляется в комплекте с clojure.reflect
пространством имен. Функция reflect
, в частности, может использоваться для отображения всех методов (и другой информации) для объекта. Это не так удобно в использовании, как show
. С другой стороны, он гораздо более общий, и довольно легко написать свою собственную версию show
использования reflect
в качестве строительного блока.
В качестве примера, если вы хотите просмотреть все методы для строки, которая возвращает строку:
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)
Комментарии:
1. Работает ли это с версией 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» на ваш объект.
Комментарии:
1. Clojure 1.10 добавляет новую функцию сбора данных. Кажется, он довольно хорошо отражает.
Ответ №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. в 1.2.0 что вы включили / использовали, чтобы получить это? это было в ядре?
2. @Arthur Это было в clojure.contrib.repl-utils. Я добавил макрос пространства имен выше для пояснения.
3. Я еще немного покопался. Clojure переходит от монолитного clojure.contrib к более модульным библиотекам. Макрос doc теперь находится в clojure.repl. Не уверен, есть ли новый дом для функции «показать». (Жаль, это было полезно). Вызов repl-utils / show из Clojure 1.3, похоже, не работает.
4.
clojure.contrib
теперь не реагирует!
Ответ №5:
IIRC это не встроенный, но он также короткий — см. Эту реализацию .
(Это может быть сейчас.)
Ответ №6:
Обычно вы делаете этот список методов, потому что ищете метод определенного типа .. скажем, все методы типа «get» в классе. Вот как вы можете сделать это для своего объекта ‘obj’:
(filter #(re-find #"get" %) (map #(.getName %) (.. obj getClass getMethods)))
#»get» — это объект регулярного выражения для поиска методов, в имени которых есть get (настройте его по своему усмотрению). Выражение map просто создает seq всех имен методов в классе объекта; seq передается анонимной функции, которая является первым параметром, переданным filter .