学习clojure第六天

2017-03-26  本文已影响0人  ukao

计算(Evaluation)

user=> "hi"
;; "hi"
user=> :foo
;; :foo
user=> [1 2 3]
;; [1 2 3]

只要有表达式,clojure都会尝试去计算,并且重复打印在控制台。如果是括号开头"(",clojure会把它当成宏,特殊形式或者函数。

函数访问(Function Calls)`

(my-func arg1 arg2 arg3)

在括号"("右边的符号就是函数的名称(my-func就是函数名称),clojure先计算出所有参数的值,再把这些参数值赋给函数。

有点绕,我的理解是像下面这种嵌套调用,先从最里层开始计算,依次计算"+"->"foo-bar"->"other-func"->"my-func2"->"my-func"

(my-func (my-func2 arg1
                   arg2)
         (other-func arg-a
                     (foo-bar arg-x
                              arg-y
                              (+ arg-xx
                                 arg-yy
                                 arg-zz))
                     arg-b))

主要注意的是,在clojure里面没有"操作符",像"+,-,*,>,=,not="都是函数名称。

宏与特殊形式(Macros and Special Form)

引号(Quoting)

'(+ 1 2 3)
;; ⇒ (+ 1 2 3)

如果是括号开头就会被当做函数,这种方式后面会介绍

Let and Locals

如果你想使用词法作用域,可以使用let表达式

(let [width     10
      height    20
      thickness 2]
  (println "hello from inside the `let`.")
  (* width
     height
     thickness))
;; ⇒ 400

再来一个列子,let会得到最后一个表达式的值。所以之前可以放一些其他的东西,例如println等。

(let [x 2
      x (* x x)
      x (+ x 1)]
  x)
;; ⇒ 5

需要注意:println函数本身计算得到的值都是nil,我们不会用它来做任何计算,这种叫做side-effect,后面会简单介绍。

Namespaces

Clojure使用命名空间进行分组,避免函数名称冲突。所有的函数都有自己的命名空间,所有的core函数都在clojure.core这个命名空间下:

(clojure.core/println "hi")

使用别名来引用库,这样就可以使用str/(为什么有斜杠还不清楚,后面应该会使用到)来代替clojure.string

(require '[clojure.string :as str])
上一篇 下一篇

猜你喜欢

热点阅读