Hello Clojure - Function

Clojure是一门函数式编程语言,function具有非常重要的地位。

Function Call

函数调用很简单,我们已经见过了很多例子:

(+ 1 2 3)
(* 1 2 3)

我们也可以将函数返回让外面使用:

user=> ((or + -) 1 2 3)
6

如果我们调用了非法的函数,会报错:

user=> (1 2 3)

ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn  user/eval1491 (form-init7840101683239336203.clj:1)

这里,1并不是一个合法的operator。

Function Define

一个函数,通常由几个部分组成:

  • defn
  • 函数名称
  • 函数说明(可选)
  • 参数列表,使用[]封装
  • 函数body

一个例子:

user=> (defn fun1
  #_=> "a function example"
  #_=> [name]
  #_=> (str "hello " name))
#'user/fun1
user=> (fun1 "world")
"hello world"
user=> (doc fun1)
-------------------------
user/fun1
([name])
  a function example
nil

Overloading

我们也可以进行函数重载,如下:

user=> (defn func-multi
  #_=> ([](str "no arg"))
  #_=> ([name1](str "arg " name1))
  #_=> ([name1 name2](str "arg " name1 " " name2)))
user=> (func-multi)
"no arg"
user=> (func-multi "1")
"arg 1"
user=> (func-multi "1" "2")
"arg 1 2"

Variable arguments

我们使用&来支持可变参数

user=> (defn func-args
  #_=> [name & names]
  #_=> (str name " " (clojure.string/join " " names)))
#'user/func-args
user=> (func-args "a")
"a "
user=> (func-args "a" "b")
"a b"
user=> (func-args "a" "b" "c")
"a b c"

Destructuring

我们可以在函数参数里面通过特定的name来获取对应的collection的数据,譬如:

user=> (defn f-vec1 [[a]] [a])
#'user/f-vec1
user=> (f-vec1 [1 2 3])
[1]
user=> (defn f-vec2 [[a b]] [a b])
#'user/f-vec2
user=> (f-vec2 [1 2 3])
[1 2]

在上面的例子里面,我们的参数是一个vector,然后[a]以及[a b]表示,我们需要获取这个vector里面的第一个以及第二个数据,并且使用变量a,b存储。

我们也可以使用map,譬如:

user=> (defn f-map [{a :a b :b}] [a b])
#'user/f-map
user=> (f-map {:a 1 :b 2})
[1 2]
user=> (f-map {:a 1 :c 2})
[1 nil]

上面这个例子我们可以用:keys来简化,

user=> (defn f-map-2 [{:keys [a b]}] [a b])
#'user/f-map-2
user=> (f-map-2 {:a 1 :b 2 :c 3})
[1 2]

我们可以通过:as来获取原始的map:

user=> (defn f-map-3 [{:keys [a b] :as m}] [a b (:c m)])
#'user/f-map-3
user=> (f-map-3 {:a 1 :b 2 :c 3})
[1 2 3]

Body

Function的body里面可以包括多个form,Clojure会将最后一个form执行的值作为该函数的返回值:

user=> (defn func-body []
  #_=> (+ 1 2)
  #_=> (+ 2 3))
#'user/func-body
user=> (func-body)
5

匿名函数

我们可以通过fn来声明一个匿名函数

user=> ((fn [name]  (str "hello " name)) "world")
"hello world"

我们也可以通过def来给一个匿名函数设置名称:

user=> (def a (fn [name] (str "hello " name)))
#'user/a
user=> (a "world")
"hello world"

当然,我们更加简化匿名函数,如下:

user=> #(str "hello " %)
#object[user$eval1584$fn__1585 0x72445715 "user$eval1584$fn__1585@72445715"]
user=> (#(str "hello " %) "world")
"hello world"

我们使用%来表明匿名函数的参数,如果有多个参数,则使用%1%2来获取,使用%&来获取可变参数。

user=> (#(str "hello " %) "world")
"hello world"
user=> (#(str "hello " %1 " " %2) "world" "a ha")
"hello world a ha"

user=> (#(str "hello " %1 " " (clojure.string/join " " %&)) "world" "ha" "ha")
"hello world ha ha"
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容