#clojure #multimethod
#clojure #мультиметод
Вопрос:
Я могу понять, как это работает:
(defmulti area :Shape)
(defmethod area :B [x] (println "Rect"))
(defmethod area :C [x] (println "Circle"))
(defmethod area :default [x] (do (println "Unknown") (:Shape x)))
(area {:Shape :B})
=> Rect
nil
(area {:Shape :Bb})
=> Unknown
:Bb
Но, просто изменив :Shape
на :Shap
, я перестаю понимать, как это отправляется:
(defmulti area :Shap)
(defmethod area :B [x] (println "Rect"))
(defmethod area :C [x] (println "Circle"))
(defmethod area :default [x] (do (println "Unknown") (:Shap x)))
(area {:Shap :B})
=> Unknown
:B
(area {:Shap :C})
=> Unknown
:C
Clojure 1.5.1 в Eclipse с плагином против часовой стрелки
Комментарии:
1. Я попробовал это в lein’s REPL, и это сработало, должно быть, проблема с CounterClockwise (бьюсь об заклад, пространство имен пользователя не было повторно инициализировано между обоими тестами).
2. Кстати, у вас, должно быть, опечатка в вашем первом примере: либо
::B
ключевое слово в определении метода не должно иметь пространства имен, либо:B
в примере вызова должно быть.
Ответ №1:
Мультиметодам не нравится, когда их переопределяют с помощью новой функции диспетчеризации. Это довольно спорная функция, но так уж обстоят дела. Чтобы изменить функцию диспетчеризации мультиметода, вы должны сначала определить ее на что-то, что не является мультиметодом (например, на nil).
(defmulti area :Shape)
(def area nil)
(defmulti area :Shap)