结构控制
常用的控制判断,if,and,or,conf
(if motor-turning?
"yes"
"no")
结构是这样的 (if <test> <then-this> <otherwise-this>)
另外在clojure里面,循环一般使用map,filter,reduce和for等内置函数,也可以使用loop或者递归的方式
这是python的写法
specific_stuff = []
for i in my_items:
if is_what_i_want(i):
specific_stuff.append(i)
clojure写法:
(def specific-stuff (filter what-i-want? my-items))
等于,判断和比较
=或者not=的方式
(if (= tries max-tries)
"you're done"
"keep going")
值的判断,可以看出来只要内容相同都是相等的
(= {:a [1 2 3] :b #{:x :y} :c {:foo 1 :bar 2}}
{:a '(1 2 3) :b #{:y :x} :c {:bar 2 :foo 1}})
;; ⇒ true
数据格式不同则不同,但==符号忽略数据类型
(= 4 4.0)
;; ⇒ false
(== 4 4.0)
;; ⇒ true
变量(Vars)
赋值
(def the-answer 42)
自定义函数
使用def+fn
(def my-func
(fn [a b]
(println "adding them!")
(+ a b)))
如何调用
(my-func 10 20) ; Returns/evaluates-to 30.
也可以使用defn
(defn my-func
"Docstring goes here."
[a b]
(println "adding them!")
(+ a b))
有几点需要注意:
1.参数a和b在vector里面,除了没有赋值
2.你可以在函数里面做任何操作,但最后一个表达式是返回值
3.如果用defn,函数名必须在第一行
函数不一定只返回一个值,也可以返回一个数据结构
(defn foo
[x]
[x (+ x 2) (* x 2)])
也可以传入数据结构
(defn bar
[x]
(println x))
(bar {:a 1 :b 2})
(bar [1 2 3])
可以定义多个参数
(defn baz
[a b & the-rest]
(println a)
(println b)
(println the-rest))
作者(不是我)喜欢自上而下的写函数,请看伪代码:
;; BROKEN pseudocode
(do-it)
(defn do-it
[]
(... (my-func-a ...)))
(defn my-func-a
[...]
(... (my-func-b ...)))
(defn my-func-b ...)
但这样是不行,clojure在写一个函数调用前需要知道,例如my-func-a在do-it中被调用,但是在后面才定义,这时我们需要使用declare,如下:
;; pseudocode
(declare do-it)
(do-it)
(declare my-func-a)
(defn do-it
[]
(... (my-func-a ...)))
(declare my-func-b)
(defn my-func-a
[...]
(... (my-func-b ...)))
(defn my-func-b ...)