Clojure запись конструкторов не первого класса? - PullRequest
7 голосов
/ 16 февраля 2011

Видимо, вы не можете вызвать apply с помощью конструктора записей:

(defrecord Foo. [id field])

(apply Foo. my-list)

завершается с ошибкой во время чтения, потому что он не ожидает Foo.в этом месте.

Единственный очевидный обходной путь, о котором я мог подумать, это добавить фабричную функцию:

(make-foo [id field] (Foo. id field))

, которую можно применять, конечно.Я что-то пропустил?Я ожидал этого от C # / Java, но думал, что это немного разочаровывает в Clojure ...

Ответы [ 3 ]

10 голосов
/ 21 января 2012

Возвращаясь к этому посту-1,3 ....

В Clojure 1.3 defrecord создает две сгенерированные функции конструктора. Дано:

(defrecord Person [first last]) 

это создаст функцию позиционного конструктора ->Person:

(->Person "alex" "miller")

и функция конструктора карты map->Person:

(map->Person {:first "string"})

Поскольку это карта, все ключи являются необязательными и принимают нулевое значение в построенном объекте.

Вы должны требовать / использовать эти функции из тех ns, где вы объявляете запись, но вам не нужно импортировать класс записи, как это было бы при использовании конструктора класса Java.

Подробнее:

6 голосов
/ 16 февраля 2011

Foo. - конструктор класса Java, поэтому он имеет типичные ограничения взаимодействия Java с тем, как вы его называете.Создание функции конструктора является распространенным решением (это также означает, что вам не нужно импортировать Foo в другом пространстве имен).

3 голосов
/ 16 февраля 2011

Проблема известна, и о ней много говорят в списке рассылки Clojure.Возможно, в будущих версиях Clojure будет добавлена ​​дополнительная поддержка.

На данный момент вы должны использовать свои собственные функции или использовать https://github.com/david-mcneil/defrecord2, который поддерживает некоторые функции, такие как:

  • printв eval'able форме
  • обеспечить функцию clojure в качестве конструктора
  • принимать именованные параметры (карты) в конструкторе
  • участвовать в мульти-методе до / после прогулки
...