clojure笔记

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))

后一个函数执行结果 ,作为前一个函数的参数

你可能感兴趣的:(clojure,JVM)