Поиск…
Определение функций
Функции определяются пятью компонентами:
Заголовок, который включает ключевое слово defn
, имя функции.
(defn welcome ....)
Необязательный Docstring, который объясняет и документирует, что делает функция.
(defn welcome
"Return a welcome message to the world"
...)
Параметры, перечисленные в скобках.
(defn welcome
"Return a welcome message"
[name]
...)
Тело, которое описывает процедуры, выполняемые функцией.
(defn welcome
"Return a welcome message"
[name]
(str "Hello, " name "!"))
Вызов:
=> (welcome "World")
"Hello, World!"
Параметры и Arity
Функции Clojure могут быть определены с помощью нуля или более параметров.
(defn welcome
"Without parameters"
[]
"Hello!")
(defn square
"Take one parameter"
[x]
(* x x))
(defn multiplier
"Two parameters"
[x y]
(* x y))
Arity
Количество аргументов, которые выполняет функция. Функции поддерживают перегрузку arity , что означает, что функции в Clojure допускают более одного «набора» аргументов.
(defn sum-args
;; 3 arguments
([x y z]
(+ x y z))
;; 2 arguments
([x y]
(+ x y))
;; 1 argument
([x]
(+ x 1)))
Арктикам не нужно выполнять одну и ту же работу, каждая из них может сделать что-то несвязанное:
(defn do-something
;; 2 arguments
([first second]
(str first " " second))
;; 1 argument
([x]
(* x x x)))
Определение вариационных функций
Функция Clojure может быть определена для принятия произвольного количества аргументов, используя символ & в списке аргументов. Все остальные аргументы собираются в виде последовательности.
(defn sum [& args]
(apply + args))
(defn sum-and-multiply [x & args]
(* x (apply + args)))
Вызов:
=> (sum 1 11 23 42)
77
=> (sum-and-multiply 2 1 2 3) ;; 2*(1+2+3)
12
Определение анонимных функций
Существует два способа определить анонимную функцию: полный синтаксис и стенографию.
Полный анонимный синтаксис функции
(fn [x y] (+ x y))
Это выражение оценивается функцией. Любой синтаксис, который вы можете использовать с функцией, определенной с defn
( &
, destructuring и т. Д.), Также можно использовать с формой fn
. defn
- фактически макрос, который просто делает (def (fn ...))
.
Синтаксис синхронных анонимных выражений
#(+ %1 %2)
Это сокращенная нотация. Используя сокращенную нотацию, вам не нужно явно указывать аргументы; им будут присвоены имена %1
, %2
, %3
и т. д. в соответствии с порядком, в котором они переданы. Если функция имеет только один аргумент, ее аргумент называется просто %
.
Когда использовать каждый
Сокращенная нотация имеет некоторые ограничения. Вы не можете разрушить аргумент, и вы не можете вставлять сокращенные анонимные функции. Следующий код вызывает ошибку:
(def f #(map #(+ %1 2) %1))
Поддерживаемый синтаксис
Вы можете использовать varargs с сокращенными анонимными функциями. Это совершенно законно:
#(every? even? %&)
Он принимает переменное количество аргументов и возвращает true, если каждый из них является четным:
(#(every? even? %&) 2 4 6 8)
;; true
(#(every? even? %&) 1 2 4 6)
;; false
Несмотря на кажущееся противоречие, можно написать анонимную функцию с именем, как в следующем примере. Это особенно полезно, если функция должна вызывать себя, а также в трассировке стека.
(fn addition [& addends] (apply + addends))