Мультиметод создается с defmulti
; Вы делаете это правильно. defmulti
нужны имя и функция отправки (и строка документации, а также некоторые опции, если вы хотите, но забудьте о них).
(defmulti random-val identity)
Когда вы реализуете мультиметод с помощью defmethod
, вам необходимо указать имя внедряемого мультиметода, значение отправки, которому он должен соответствовать, а затем функцию tail (arglist плюс все, что вы хотите, чтобы он делал).
(defmethod random-val :trans [t] (random-trans))
(defmethod random-val :amt [t] (random-amt))
Вы получаете java.lang.IllegalArgumentException: No method in multimethod 'random-val' for dispatch value: null (NO_SOURCE_FILE:0)
, потому что когда назначенная вами функция диспетчеризации random-val
, :val-type
применяется к любому другому ключевому слову, оно дает вам null
. Когда Clojure пытается найти метод, соответствующий этому значению диспетчеризации, происходит сбой.
Но даже если это не сработало там, ваши определенные методы имеют 0 арность (не принимают значений), так что вам тоже нужно это исправить (сделано выше).
Наконец, это не похоже на хорошее использование протоколов. Просто используйте две отдельные функции, random-amount
и random-trans
.
Обратите внимание, что веб-сайт Clojure имеет хорошее объяснение мультиметодов.