clojure实战——符号&@#'+-*/

来源:互联网 发布:2017中美人工智能创投 编辑:程序博客网 时间:2024/05/17 08:28

clojure实战——符号&@#’+-*/

本博客继续对clojure语言中一些符号进行讲解:&,@,-‘,#’。

保持“剩下的元素”——&

&:保持”剩下的元素”

在解构中,可以用&符号保持解构剩下来的元素,有点像java中的可变参数

示例:

(comment  (defn &test    [a & rest]    rest)  (&test 1 2 3 4)  ;; => '(2 3 4)  ;; 剩下的元素被放入到rest中,rest是一个列表,而不是vector。  (let [[a & b] [1 2 3]]    b)  ;; => (2 3)  (defn &test2    [a & [rest]]    rest)  (&test2 1 2 3 4)  ;; => 2  ;; 有趣的现象:剩下的元素为'(2 3 4),它被'[rest]解构,并将r绑定到第一个元素2  ;; 类似于:(let [[r] '(2 3 4)] r) => 2  (defn &test3    [a & [r h a]]    (conj [] r h a))  (&test3 1 2 3 4)  ;; => [2 3 4]  ;; r、h、a 分别为2、3、4。  )

解引用——@

@:解引用

@等同于deref函数
clojure中有很多实体都是可以解引用的,如delay、future、promise以及所有引用类型:atom、ref、agent、var。

示例:

(comment  (def atom-a (atom 10))  @atom-a  ;; => 10  (def a-var 10)  @(var a-var)  ;; => 10  )

获取符号指向的Var——#’

#’:用于获得一个符号(Sysmbol)所指向的Var。

clojure中,Var有def来创建
等同于var函数,返回值都是Var
clojure中,使用了两层”指针”来绑定”Sysmbol->Var->Function”
也就是说,我们通过一个符号来调用一个函数其实还经历了Var这一层:先找到符号指向的Var,再找到Var指向的函数。
这样做的好处是,我们可以动态地绑定Var指向某个具体的函数(有点多态的感觉)。

示例:

(comment  #'+  ;; => #'clojure.core/+  (var +)  ;; => #'clojure.core/+  ;; 表明符号+指向的Var是#'clojure.core/+  ;;查看#'和var的返回值类型  (class (var +))  (class #'+)  ;; => clojure.lang.Var  ;; 说明返回值类型是一个Var  ;; 那#'clojure.core/+指向的函数是什么?可以对Var解引用  @#'+  ;; => #object[clojure.core$_PLUS_ 0x77730aa7 "clojure.core$_PLUS_@77730aa7"]  ;; 说明指向的函数是 #object[clojure.core$_PLUS_ 0x77730aa7 "clojure.core$_PLUS_@77730aa7"]  ;; Var默认是静态的(static),不可被动态绑定  (def var-x 1)  (binding [var-x 1]    var-x)  ;; => CompilerException java.lang.IllegalStateException: Can't dynamically bind non-dynamic var: clojure-async.symbols/var-x,  ;; 在创建一个Var时,可以指定它是可动态绑定的。  ;; 下面建立了一个可动态绑定的Var,并绑定一个根值为:default-value  (def ^:dynamic var-y :default-value)  (binding [var-y 2]    var-y)  ;; => 2  ;; 被动态绑定为2,但是它只作用于binding的作用域内。  var-y  ;; => :default-value  )

减——-‘

-‘:加强版的减。

-‘函数可以接受一个参数,当只有一个参数时,默认被减数为0;当有多个参数时,和普通减号一样。
支持任意精度,不会像普通-那样出现越界异常。

示例:

(comment  (-' 3)  ;; => -3 默认被减数为0  (-' 5 2 1)  ;; => 2 和普通符号一样  (- 0 9000000000000000000 1000000000000000000)  ;; => ArithmeticException integer overflow  clojure.lang.Numbers.throwIntOverflow (Numbers.java:1521)  (-' 0 9000000000000000000 1000000000000000000)  ;; => => -10000000000000000000N  )

加——+’

+’:加强版的+

接受0到N个数值的参数
支持任意精度

示例:

(comment  (+)  (+')  ;; => 0  (+ 1 Long/MAX_VALUE)  ;; => ArithmeticException integer overflow  clojure.lang.Numbers.throwIntOverflow (Numbers.java:1521)  (+' 1 Long/MAX_VALUE)  ;; => 9223372036854775808N  )

乘——*’

‘:加强版的

接受0到N个数值的参数
支持任意精度

示例:

(comment  (*)  (*')  ;; => 1  (* 2 Long/MAX_VALUE)  ;; => CompilerException java.lang.ArithmeticException: integer overflow, compiling  (*' 2 Long/MAX_VALUE)  ;; => 18446744073709551614N  )
原创粉丝点击