Можно ли сделать наследование типов данных в Clojure? - PullRequest
8 голосов
/ 12 декабря 2011

Например, если у меня есть две разные записи, но они имеют несколько общих полей, есть ли способ сделать так, чтобы обе записи имели общую базовую запись?Кажется, что протоколы допускают только объявление сигнатур методов.

Ответы [ 2 ]

4 голосов
/ 19 января 2012

Вы должны программировать на основе абстракции, а не конкретных полей, т. Е. Использовать протокол, чтобы записи могли иметь общий интерфейс.Например, если все ваши типы записей должны возвращать свойство 'string', создайте протокол с помощью метода 'get-string' и распространите его на каждый тип записи.

(defprotocol SQL
  (get-string [t]))

(defrecord Thing [name f1 f2]
  SQL
  (get-string [t] (str name)))

(defrecord AnotherThing [name f1 f2 f3 f4 blah]
  SQL
  (get-string [t] (str name)))

Если вы окажетесьсоздавая одну и ту же реализацию для конкретного метода протокола, вы всегда можете «определить» (непубличную функцию) реализацию и использовать ее в качестве реализации в каждом типе записи.

4 голосов
/ 12 декабря 2011

Я не думаю, что это возможно на данный момент.

defrecord - это просто макрос, и вы можете проверить, что он делает, используя macroexpand, например:

(macroexpand '(defrecord User [Name Age]))

Так что, если вы хотите такое наследование записей, вам, вероятно, потребуется реализовать макрос для этого. Но я бы не стал утверждать, что наследование - это то, чего я стараюсь избегать, потому что оно ведет к сложности.

...