Я уверен, что ваш вопрос показывает упрощенный случай относительно того, что вам действительно нужно выполнить.Что касается общего решения, я согласен, что протоколы - достойный подход.
Вы спрашивали о мультиметодах, но проблема, с которой вы столкнетесь, связана с функцией диспетчеризации.defmulti принимает диспетчерскую функцию, которая будет вызываться в аргументах реальной функции.Функция отправки должна возвращать значение, которое затем можно использовать для выбора того, какая реализация метода будет вызываться.
Проблема в том, что вы отправляете?Чтобы различать типы коллекций, вы должны получить что-то вроде этого:
(defmulti stringify class)
(defmethod stringify clojure.lang.PersistentVector [v] ...)
(defmethod stringify clojure.lang.PersistentArrayMap [m] ...)
;;; More dispatching on concrete class names
Что ж, как только вы увидите конкретные имена классов clojure.lang, появляющиеся в вашем коде, все виды аварийных сигналов должны бытьухожуОни слишком специфичны ... они сломаются, если изменится базовая библиотека Clojure, они не будут работать очень чисто с взаимодействием Java, они не будут охватывать пользовательские типы, которые реализуют Seqable ... короче,они являются нарушением абстракции.
Каждый раз, когда у вас возникнет искушение отправлять имена классов, будь то из Clojure, Java или сторонних библиотек, вы должны всегда тянуться к exten-typeвместо этого.