clojure语法小记

原创 2013年12月02日 17:13:42

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

理解clojure语法(1)

然后counter被绑定到匿名函数`#(swap! tick inc)`的地址。 当counter绑定完之后,每次调用counter :`(counter)` 解释器就会找到counter ,也就是匿...
  • yin_wuzhe
  • yin_wuzhe
  • 2016年05月04日 21:58
  • 912

Markdown---语法小记

在CSDN上的文章现在都习惯使用Markdown来编写比较方便美观,这里小结下常见的Markdown语法下:1.标题:方式1 # H1 ## H2 ### H3 #### H4 ##### ...
  • netdxy
  • netdxy
  • 2016年01月23日 01:00
  • 1752

2013第四届蓝桥杯 C/C++本科A组 真题答案解析【交流帖】

今年的蓝桥杯又已经结束了,做的还是不怎么样,很多题目不难但就是算不出最终的结果,很是纠结,看来路还很长,另外昨天(2013-5-7)也受到了也受到了微软的thank you letter了,哎,都是苦...
  • on_way_
  • on_way_
  • 2013年05月07日 12:20
  • 9960

clojure-基本语法-集合(一)

Clojure提供以下集合类型: list, vector, set, map。并且可以使用Java里面提供的集合类型。所有的clojure集合是不可修改的、异源的以及持久的。不可修改表示集合产生之后...
  • codemosi
  • codemosi
  • 2015年03月27日 16:39
  • 609

Clojure教程-基本语法

目录 1 简介 2 核心语法 3 代码功能 3.1 读取简繁字典 3.2 进行简繁翻译 3.3 读取不需要翻译的文字 3.4 过滤不翻译的文字 3.5 提供给Jav...
  • ivan_pig
  • ivan_pig
  • 2014年01月07日 21:51
  • 1928

clisp, scheme 和 clojure 初学习

clojure 初学习有时候我们需要一种粘合剂,它本身并不需要提供庞大的功能,但是能够很容易地调用已经存在的类库。我们自然联想到微软的COM和JavaScript脚本这样的东西,的确和这个很类似,但是...
  • cheungmine
  • cheungmine
  • 2013年11月11日 10:24
  • 2853

clojure-基本语法-集合(二)

三、映射Map  Map存储一个键-值对的集合。键和值都可以是任何数据类型的对象,无论是基本数据类型还是其它映射。然而,使用关键字来作为映射的键非常合适,因此它们经常在应用映射的场合被使用。cloj...
  • codemosi
  • codemosi
  • 2015年03月27日 16:40
  • 627

规则引擎 clara-rules

本文的主题是规则引擎,主要内容包括规则引擎的实现算法 rete算法,clojure开源的规则引擎clara-rules对规则的处理方式和特点,以及clojure edn文件格式处理等内容。那么什么是规...
  • yin_wuzhe
  • yin_wuzhe
  • 2016年11月01日 17:38
  • 1106

Clojure 学习入门(18)—— 数据类型

如何表示和处理数据Clojure是一种动态类型语言,这意味着你在程序中永远不需要明确定义符号、函数、或者参数的数据类型。但是,所有的值仍然有一个类型。字符串时是字符串,数字是数字,列表是列表,等等。如...
  • sunboy_2050
  • sunboy_2050
  • 2014年04月10日 22:31
  • 9293

Clojure中Vector和List的区别及其相关函数

Clojure是一门动态类型的语言,运行时才会做类型检查。它也不会像java这种面向对象编程语言,再调用一个对象的函数时,首先这个函数必须是属于某个对象的函数,否则检查报错。所以对于clojure中的...
  • zdplife
  • zdplife
  • 2016年08月13日 17:13
  • 1185
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:clojure语法小记
举报原因:
原因补充:

(最多只允许输入30个字)