(defn add [v1 v2 & others] ;;&后面的是可变参数
(+ v1 v2
(if others ;;判断可变参数列表是否是空,如果不是累加列表中的值,否则返回0
(reduce + 0 others) ;;使用reduce函数计算others的数字之和。
0
)
)
)
(defn -name & decls)作用和defn类似,唯一的不同是创建的函数是私有的
说法不一致,详情参考:http://www.bertschneider.de/2011/01/11/Assoc-vs-Update/
assoc,只允许更新数据结构的第一层。处理数据的性能最高,几乎是assoc-in的两倍。
assoc-in 和update-in 可以使用路径表达式改变数据结构的内层。
如果新的值不依赖旧值,assoc-in就可以满足需求,不需要使用update-in;在有依赖关系时,使用update-in
(defrecord Person [fname lname address])
(defrecourd Address [street city state zip])
(def stu (Person. "Stu" "Halloway" (Address. "200 N Mangum" "Durham" "NC" 27707)))
(assoc stu :fname "Stuart")
(upate-in stu [:address :zip] inc)
#’x 等价于( var x)
(loop [i 0]
(when (< i 5)
(printlin i)
(recur (inc i )))) ;loop i will take this value
如果递归的层次太深的话, 可能会产生内存不足。一些编程语言用“tail call optimization”(TCO)的技术来解决这个问题。在clojure中避免这个问题的方法是使用loop和recur。
loop/recur组合把一个递归的调用变成一个迭代(迭代与递归,详情看另一篇文章),迭代不需要占用栈空间。loop special form 跟let special form 类似的地方就是它们都会建立一个本地binding,但是同时它也建立一个递归点,这个递归点就是recur的参数里面的那个函数。loop给这些binding 一个初始值。对recur的调用使得程序的控制权返回给loop并给那些本地binding赋了新的值。给recur传递的参数一定要和loop创建的binding个数一样,recur只能出现在loop的最后一行。
6.conj 给集合添加新值
(conj coll x)(conj coll x & xs)
(conj #{1 2 3} 4) ;=>#{1 2 3 4}
7.disj删除集合原有的值
(disj #{1 2 3} 1) ;=>#{2 3}
8.seq? sequential? coll?
(1)如果参数实现了 ISeq 接口,也就是说提供了first,rest,cons方法,则结果为true
(seq? [1 2])
false
(seq? (seq [1 2]))
true
(2)sequential? 实现了Sequential接口时为true,比如list而map不是
(sequential? [])
true
(sequential? {})
false
(3)colls? 如果参数实现了IPersistentCollection,则返回true
(coll? {:a 1})
true
(coll? (java.util.HashMap.))
false
9.直接将set当做函数测试是否包含某值
(#{1 2 3} 1)
;=>1(有就返回原有的值)
(#{1 2 3} 4)
;=>nil (没有返回nil)
10.求交集和并集
;交集
(clojure.set/intersection s1)
(clojure.set/intersection s1 s2)
(clojure.set/intersection s1 s2 & sets)
(clojure.set/intersection #{1 2 3} #{2 3 4}) ;交集
#{1}
;返回一个集合,第一个集合中的元素排除掉剩余集合的元素
(clojure.set/difference s1)
(clojure.set/difference s1 s2)
(clojure.set/difference s1 s2 & sets)
(clojure.set/difference #{1 2} #{2 3})
#{1}
(user '[clojure.set :only [intersection])
;使用require导入一个模块
(require 'clojure.string)
;从一个模块中调用函数
(clojure.string/blank? "") ;=>true
;在导入模块的时候自定义名称
(require '[clojure.string :as str])
(str/replace "This is a test." #"[a-o]" str/upper-case)
;可以使用”:require”从一个命名空间中引入模块
;如果使用:require,就没有必要把模块“引”(前面加个单引号)起来了
(ns test
:require
[clojure.string :as str]
[clojure.set :as set])
;使用import类引入java模块
(import java.util.Date)
;也可以从一个命名空间中引入
(ns test
(:import java.util.Date
java.util.Calendar))
;类名字加“.”用来创建对象
(Date.)
;使用.来调用方法,或者使用“.方法名”简写的方式
(.(Date.) getTime)
(.getTime (Date.)) ;等价
;使用/来调用静态方法
(System/currentTimeMillis)