Assoc и disoc на записи Clojure
Почему существует разница в типах возврата assoc
и dissoc
в Clojure, когда их аргумент является записью? Я имею в виду, что assoc
"несуществующий ключ" все еще возвращает запись, но dissoc
'с существующим ключом возвращает карту.
Но, в некотором смысле, оба должны производить либо карту, либо запись, но не проявлять по-разному поведение. В чем причина этой несходства?
Ответы
Ответ 1
В экземплярах записи будут включены все поля, объявленные в определении записи.
Когда объявленное поле удаляется из экземпляра, эта гарантия будет нарушена. Следовательно, возвращается карта.
По-видимому, они не гарантируют исключения всех полей, не объявленных в определении записи, поэтому новые поля могут быть добавлены в экземпляры.
Ответ 2
Запись будет преобразована в обычную карту clojure, только если вы dissoc
одно из своих предопределенных полей. Это очень разумное поведение, потому что записи не могут иметь поля undefined.
Рассмотрим следующий код:
(defrecord Point [x y])
(def p (Point. 1 2)) ; => Point{:x 1, :y 2}
(assoc p :x 3) ; => Point{:x 3, :y 2}
(dissoc p :x) ; => {:y 2}
(assoc p :z 3) ; => Point{:x 1, :y 2, :z 3}
(dissoc p :z) ; => Point{:x 1, :y 2}
(-> p
(assoc :z 3) ; => Point{:x 1, :y 2, :z 3}
(dissoc :z)) ; => Point{:x 1, :y 2}
Как вы можете видеть, оба assoc
и dissoc
возвращают запись, если она удовлетворяет определению Point
.