Предположим, у меня есть этот мультиметод
(defmulti m (fn [v] [(:type v)]))
(defmethod m [Object] [k] (prn "Object"))
(defmethod m [:mykwd] [k] (prn "mykwd"))
Когда я вызываю его с подклассом Object
, он корректно отправляется первой реализации:
(m {:type String})
"Object"
С :mykwd
он также работает как ожидалось:
(m {:type :mykwd})
"mykwd"
Но когда я предоставляю другое ключевое слово, я получаю исключение:
(m {:type :anotherkwd})
#<CompilerException java.lang.IllegalArgumentException: No method in multimethod 'm'
for dispatch value: [:anotherkwd] (NO_SOURCE_FILE:0)>
Как именно эта отправка работает?
Можно ли сохранить это поведение для наследования классов и при этом иметь реализацию по умолчанию, которая перехватывает все ключевые слова?
EDIT Этот пример упрощен, но он мне нужен для работы с двоичными функциями. Моя настоящая потребность ниже. Я не понимаю, как я могу применить :default
к нему.
(defmulti m (fn [arg mp] [(class arg) (:type mp)]))
Тогда я ищу способ определить его для случая, когда arg
- это nil
, а (:type mp)
- что-нибудь. Это работает, когда значение для :type
является классом, но не для любое ключевое слово :
(defmethod m [nil Object] [arg mp] (prn "Whatever"))