storm-clojure
clojure方法定义 defn 宏用来定义一个函数。它的参数包括一个函数名字,一个可选的注释字符串,参数列表,然后一个方法体。而函数的返回值则是方法体里面最后一个表达式的值。所有的函数都会返回一个值, 只是有的返回的值是nil。 fn定义匿名函数,通过fn定义的函数可以包含任意个数的表达式,而通过#(..)只能使用一个表达式 ,如果想包含多个表达式,那么就可以用do包含起来,如果只有一个参数,通过%获得,如果有多个参数可以通过%1 %2获得
(def years [1940 1944 1961 1985 1987])
(filter (fn [year] (even? year)) years) ; long way w/ named arguments -> (1940 1944)
(filter #(even? %) years) ; short way where % refers to the argument
宏defmulti
和defmethod
经常被用在一起来定义 multimethod. 宏defmulti
的参数包括一个方法名以及一个dispatch函数,这个dispatch函数的返回值会被用来选择到底调用哪个重载的函数。宏defmethod
的参数则包括方法名,dispatch的值, 参数列表以及方法体。一个特殊的dispatch值:default
是用来表示默认情况的 — 即如果其它的dispatch值都不匹配的话,那么就调用这个方法。defmethod
多定义的名字一样的方法,它们的参数个数必须一样。传给multimethod的参数会传给dipatch函数的。实现类似java的重载
(defmulti what_am_i class)
(defmethod what_am_i Number [args] (println args "is num"))
(defmethod what_am_i String [args] (println args "is String"))
(defmethod what_am_i :default [args] (println args "is default"))
(what_am_i 19)
(what_am_i "luochao")
(what_am_i true)
clojure提供了很多函数来充当谓词功能,测试条件是否成立,他的返回值是ture或者false,在clojure语言中,false和nil被解释成false,其他的都为true包括0,谓词函数一般以?结尾,class?
,coll?
,decimal?
,delay?
,float?
,fn?
,instance?
,integer?
,isa?
,keyword?
,list?
,macro?
,map?
,number?
,seq?
,set?
,string?
clojure反射是一种获取对象的特性
structMap
定义一个
(def vehicle-struct (create-struct :make :year :day))
or (defstruct vehicle-struct :make :year :day)
(def vehicle (struct vehicle-struct "to" 121 12))
定义一个访问函数 (def make (accessor vehicle-struct :make))
(make vehicle)
(vechicle )
partial
函数创建一个新的函数 — 通过给旧的函数制定一个初始值
; Note the
use
of
def
instead of
defn
because partial returns
; a function that is then bound to
"times2"
.
(
def
times2 (partial * 2))
(times2 3 4) ; 2 * 3 * 4 -> 24
reduce
函数接收一个需要两个参数的函数, 一个可选的value以及一个集合。它会以value以及集合的第一个元素作为参数来调用给定的函数(如果指定了value的话), 要么以集合的第一个元素以及第二个元素为参数来调用给定的函数(如果没有指定value的话)。接着就以这个返回值以及集合里面的下一个元素为参数来调用 给定的函数,知道集合里面的元素都被计算了 — 最后返回一个值. 这个函数与ruby里面的inject
以及Haskell里面的foldl
作用是一样的。
memoize
函数接受一个参数,它的作用就是给原来的函数加一个缓存,所以如果同样的参数被调用了两次, 那么它就直接从缓存里面返回缓存了的结果,以提高效率, 但是当然它会需要更多的内存。(其实也只有函数式编程里面能用这个技术, 因为函数没有side-effect, 多次调用的结果保证是一样的)
map
对一个给定的集合里面的每一个元素调用一个指定的方法,然后这些方法的所有返回值构成一个新的集合(LazySeq)返回。这个指定了函数也可以有多个参 数,那么你就需要给map多个集合了。如果这些给的集合的个数不一样,那么执行这个函数的次数取决于个数最少的集合的长度。比如:
1
2
3
|
; The next line uses an anonymous function that adds 3 to its argument.
(
map
#(+ % 3)
[
2 4 7
]
) ; -> (5 7 10)
(
map
+
[
2 4 7
]
[
5 6
]
[
1 2 3 4
]
) ; adds corresponding items -> (8 12)
|
apply
把给定的集合里面的所有元素一次性地给指定的函数作为参数调用,然后返回这个函数的返回值。所以apply与map的区别就是map返回的还是一个集合,而apply返回的是一个元素, 可以把apply看作是SQL里面的聚合函数。比如:
1
|
(
apply
+
[
2 4 7
]
); -> 13
|
(defn teenager? [age] (and (>= age 13) (< age 20)))
(def no-teen? (complement teenager?))
(println (no-teen? 47))
complement取反
(defn time2 [n] (* n 2))
(defn minus3 [n] (- n 3))
(def my-composition (comp time2 minus3))
(println (my-composition 4))
后一个函数执行结果 ,作为前一个函数的参数