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

Assoc и disoc на записи Clojure

Почему существует разница в типах возврата assoc и dissoc в Clojure, когда их аргумент является записью? Я имею в виду, что assoc "несуществующий ключ" все еще возвращает запись, но dissoc 'с существующим ключом возвращает карту.

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

4b9b3361

Ответ 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.