clojure语法小记

本文介绍了Clojure编程语言的一些核心语法特性,包括可变参数、列表创建、引用、展开、引用插入、匿名函数、映射操作、应用函数、符号绑定、宏中的符号生成、笛卡尔积、数据结构操作、时间戳获取、对象创建、数据处理管道和宏定义等概念,旨在帮助读者理解Clojure的编程方式。
摘要由CSDN通过智能技术生成

1. & varparam

相当于java中的可变参数, eg (defmacro defserverfn [name & body] ...), body表示其余的一个或者多个参数。

 

2. (list 1 2 3)

(1 2 3) 创建一个新列表。

 

3. unquote

`(1 2 ~(list 3 4))   =>  (1 2 (3 4)) 对表达进行evaluate操作。

 

4. unquote-splice

`(1 2 ~@(list 3 4))   =>  (1 2 3 4) 对表达式进行evaluate操作,去掉操作后的括号。

 

5. '(1 2 3)

quote,原文显示列表,不对列表进行evaluate操作。

 

6. #(operator %1 %2 %3 %4 %5)

(map #(+ % 3) [2 4 7]) ; -> (5 7 10) 创建匿名函数。


7. (map #(+ % 3) [2 4 7]) ; -> (5 7 10)

将函数一次应用于指定列表数据中的每一个数据,函数是源,数据是标的,类似java在一个数据集上使用迭代器循环操作。

 

8. (apply + [2 4 7]); -> 13

把给定的集合里面的所有元素一次性地给指定的函数作为参数调用,然后返回这个函数的返回值,数据是源,函数是标的。

与map的区别就是map返回的还是一个集合,而apply返回的是一个元素, 可以把apply看作是SQL里面的聚合函数。

 

9. (let [a 1 b 2] (+ a b))

symbol binding. make a=1 and b=2 , then compute a+b, and finally print the result。

 

10. prefix#

在宏中使用,auto-gensym,在宏编译时产生唯一的symbol名字,防止命名冲突。

 

11. (doseq [x [1 2 3] y [1 2 3]] (prn (* x y)))

将参数x, y在各自指定的数据集上进行笛卡尔积混排后,按照指定函数进行运算,返回结果列表,类似java中的多重for循环。


12. (assoc {:key1 "old value1" :key2 "value2"} :key1 "value1" :key3 "value3")  ->  {:key3 "value3", :key2 "value2", :key1 "value1"}

将原始map中指定的key替换为指定的值,如果原始key不存在,则新增。


13. (defrecord Employee [name room])

定义数据类型Employee, 其中有两个字段,名称分别为name和room。

(def emp (Employee. "John Smith" 304))

实例化一个Employee对象。

 (:name emp) 

获取emp对象中的name字段值。


14. (str 1 2 3) -> "123"

字符串连接。


15. (defnk f [:b 10] (inc b)) 

和defn的区别在于可以为参数指定默认值,实际调用的时候如果不传参数,会使用默认值进行计算,否则采用传入的参数

(f) -> 11

(f :b 100) -> 101


16. (a/b)

调用命名空间a下的函数b.


17. (.. class-or-object (method1 args) (method2 args) (method3 args) )

串行连续调用多个函数,第一个函数的返回值作为第二个函数的第一个参数,以此类推。


18. 下划线(_)

经常在clojure代码的let语句块中看到下划线,例如:(let [a (expr_for_a) _ (println "log") b (expr_for_b)] (expr_body))

由于let中参数绑定均为k v 形式,在有些情况下,我们只在乎v表达式的执行,而不在乎返回值,此时k的位置需要用下划线"_"来占据,依次告知编译器,我们不在乎表达式的返回值。


19. for

作用和doseq类似,区别是可以使用额外的条件表达式进行笛卡尔积的筛选,支持的算子有:let  :when :while,例如:

(for [x [0 1 2 3 4 5] :let [y (* x 3)] :when (even? y)] y)  => (0 6 12)

将y设置为x*3,并且过滤掉奇数。

(for [x (range 3) y (range 3) :when (not= x y)] [x y]) => ([0 1] [0 2] [1 0] [1 2] [2 0] [2 1])

(for [x (range 3) y (range 3) :while (not= x y)] [x y]) => ([1 0] [2 0] [2 1])

将list x和y进行笛卡尔乘积,可以看到筛选算子when和while的区别在于while在list x中的每个元素第一次遇到不符合条件的list y中的元素时,list y后面的元素便全部忽略,从list x中的下一个元素开始重新对list y进行笛卡尔乘积。


20. 数据结构

‘(a b c) 链表

[a b c] 数组

#{a b c} set

{:a 1, :b 2, :c 3} map


21. assoc

应用于数据结构map, vector

(assoc {:key1 "old value1" :key2 "value2"} :key1 "value1" :key3 "value3") => {:key3 "value3", :key2 "value2", :key1 "value1"}

拷贝一个新map,同名的key则覆盖旧value,不同的key则追加。


22. (System/currentTimeMillis)

斜杠用于表示静态方法调用


23. (Integer. "100")

创建一个Integer对象,后面的参数是构造函数中所需参数。(注意Integer后面的点)


24. (-> 100 (Integer.) .toString)

向右的单箭头称为thread-first,按照从左到右的顺序依次将第一个form的计算结果作为第一个参数传入紧接下来右边的form. 将各个处理节点作为数据处理管道串联起来。


25. 在定义宏的时候可以看到三个特殊的语法糖  ~  ~@  #

例如:

(defmacro mymacro [number & body]
    `(let [number# ~number] 
(cond 
(> number# 0) "positive"
(= number# 0) "zero"
:else ~@body)))

`称为syntax quote,表示宏主体里面的内容都会按照字面被展开,除了带波浪线的元素外,波浪线标注的元素number在展开时以其对应的值来代替,~@表示body是一个序列。number#是用来产生一个独特的符号名而不会和其他符号名冲突。

26. 获取map中指定key的值
(def simple_map {:a 1, :b 2, :c 3})
(:a simple_map)

27. type hint
(defn ^String substr [^String s ^Integer begin ^Integer end] (.substring s begin end))
使用^提示clojure编译器,方法的参数和返回值的类型。


28. #(get % key)

定义一个匿名函数,%表示函数的第一个参数(第2, 3个函数用%2, %3表示),该匿名函数获取参数中键值为key对应的value。


29. ((comp str + )  1 2 3)

comp将多个函数按照right-to-left的顺序应用于指定数据集上,上述REPL运行结果为"6"。


30. (concat [1] [2] '(3 4) [5 6 7] #{9 10 8})

连接集合 (1 2 3 4 5 6 7 8 9 10)


31. (repeat 5 "x")

("x" "x" "x" "x" "x")


32. (iterate inc 5)

迭代计算 (5 6 7 8 9 10 11 12 13 14 15 ... n

如果不用take配合,最终会导致OOM。


33. (merge {:a 1 :b 2 :c 3} {:b 9 :d 4})

合并多个map,对于重复重现的Key,后面出现的会覆盖前面同样的Key。


34. (set '(1 1 2 3 2 4 5 5))

返回一个唯一集合 #{1 2 3 4 5}


35. (group-by f coll)

group-by根据算子f对集合coll进行排序,返回一个map,其中key为f计算的结果,key对应的value为coll中的对应元素,map按照key进行排序,

(group-by count ["a" "as" "asd" "aa" "asdf" "qwer"])  ->  {1 ["a"], 2 ["as" "aa"], 3 ["asd"], 4 ["asdf" "qwer"]}


36. (vals {:a "foo", :b "bar"})

返回map对应value的序列 ("foo" "bar")

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值