Подтвердить что ты не робот

Получение имени типа структуры Clojure?

При определении типа структуры и экземпляра я могу напечатать значение и получить тип реализации "struct":

(defstruct person :name :age)
(def p (struct person "peter" 30))

user=> p
{:name "peter", :age 30}
user=> (type p)
clojure.lang.PersistentStructMap

Но можно ли указать, является ли p экземпляром типа struct "person"?

4b9b3361

Ответ 1

Смотрите: этот пост в группе Clojure Google. В общем, групповые архивы - сундук с сокровищами...

Примечание. Функциональность структур заменяется записями. Тогда это уже не проблема, потому что записи действительно определяют новый тип, и вы можете проверить с помощью instance?, есть ли что-то из записи определенного типа.

Ответ 2

Немного уродливый, но он работает:

(require '[clojure.contrib.java-utils :as cj])

(defn struct-instance? [struct-def sm]
  (= (cj/wall-hack-field clojure.lang.PersistentStructMap "def" sm)
     struct-def))

(struct-instance? person p)
; => true

(struct-instance? person (conj p [:foo 1] [:bar 2]))
; => true

(defstruct foo :k1 :k2)
(struct-instance? foo p)
; => false

Материал из clojure.contrib.java-utils будет доступен в 1.2 в части clojure.java, частично в clojure.contrib.java (я думаю?), а также в clojure.contrib.java-utils для обратной совместимости... Хотя детали могут все еще меняться, Во всяком случае, Meikel прав насчет замены defrecord defstruct, поэтому, если вы работаете над 1.2, предпочитайте это.