Как Clojure определить, сколько аргументов ожидает анонимная функция (созданная с помощью нотации #...
)?
user=> (#(identity [2]) 14)
java.lang.IllegalArgumentException: Wrong number of args (1) passed to: user$eval3745$fn (NO_SOURCE_FILE:0)
Как Clojure определить, сколько аргументов ожидает анонимная функция (созданная с помощью нотации #...
)?
user=> (#(identity [2]) 14)
java.lang.IllegalArgumentException: Wrong number of args (1) passed to: user$eval3745$fn (NO_SOURCE_FILE:0)
#(println "Hello, world!")
→ нет аргументов
#(println (str "Hello, " % "!"))
→ 1 аргумент (%
является синонимом %1
)
#(println (str %1 ", " %2 "!"))
→ 2 аргумента
и т.д. Обратите внимание, что вам не нужно использовать все %n
s, количество ожидаемых аргументов определяется наивысшим n. Поэтому #(println (str "Hello, " %2))
все еще ожидает два аргумента.
Вы также можете использовать %&
для захвата аргументов покоя, как в
(#(println "Hello" (apply str (interpose " and " %&))) "Jim" "John" "Jamey")
.
Из Clojure docs:
Anonymous function literal (#())
#(...) => (fn [args] (...))
where args are determined by the presence of argument literals taking the
form %, %n or %&. % is a synonym for %1, %n designates the nth arg (1-based),
and %& designates a rest arg. This is not a replacement for fn - idiomatic
used would be for very short one-off mapping/filter fns and the like.
#() forms cannot be nested.
Это дает вам ошибку, что вы передали один аргумент вашей анонимной функции, ожидавшей нул.
Арность анонимной функции определяется наивысшим аргументом, указанным внутри.
например.
(#(identity [2]))
→ arity 0, 0 аргументы должны быть переданы
(#(identity [%1]) 14)
→ arity 1, 1 аргумент должен быть передан
(#(identity [%1 %2]) 14 13)
или
(#(identity [%2]) 14 13)
→ arity 2 и т.д.
(#(identity [%&]) 14)
→ arity n, любое количество аргументов может быть передано
Вам нужно обратиться к аргументам с% 1,% 2 и т.д., чтобы заставить функцию требовать много аргументов.