Ответ 1
Я думаю, что deftype
может быть способ пойти, однако я бы принял переход к методам доступа. Вместо этого просмотрите clojure.lang.ILookup
и clojure.lang.Associative
; это интерфейсы, которые, если вы реализуете их для своего типа, позволят вам использовать get
/get-in
и assoc
/assoc-in
, что сделает гораздо более универсальное решение (вы не только сможете изменить но, возможно, также использовать функции, встроенные в библиотеку стандартных коллекций Clojure для управления вашими структурами).
Несколько замечаний:
-
Вероятно, вы должны начать с
defrecord
, используяget
,assoc
и Co. со стандартными реализациямиdefrecord
ILookup
,Associative
,IPersistentMap
иjava.util.Map
. Возможно, вам удастся пройти довольно длинный путь.Если/если их уже недостаточно, посмотрите на источники для
emit-defrecord
(частная функция, определенная вcore_deftype.clj
в Clojure источниках). Это довольно сложно, но это даст вам представление о том, что вам может понадобиться реализовать. -
Ни
deftype
, ниdefrecord
в настоящее время не определяют любые функции factory для вас, но вы должны, вероятно, сделать это сами. Проверка работоспособности входит в эти функции (и/или соответствующие тесты). -
Более концептуально сложные операции, конечно, идеально подходят для функций протокола, построенных на основе
get
и Co.
О, и посмотрите на gvec.clj
в источниках Clojure для примера того, как может выглядеть какой-то серьезный код структуры данных, написанный с помощью deftype
. Сложность здесь отличается от того, что вы описываете в вопросе, но все же это один из немногих примеров программирования пользовательской структуры данных в Clojure, доступных в настоящее время для общественного потребления (и это, конечно же, отличный качественный код).
Конечно, это то, о чем мне говорит моя интуиция в это время. Я не уверен, что на данном этапе существует много способов создания идиом, что с deftype
фактически не было выпущено и все.: -)