clojure 新手指南(13):序列&向量

序列

我们知道clojure是Lisp的一种方言,那么这也意味着对这门语言必然植根于“列表解析”。但是在Clojure中,我们优先使用"序列"来创造列表和管理列表中的元素。

列表

之前我们说过,Lisp系列语言整个都建立在列表之上。我们使用"list"函数来创建一个列表,但后面你就会发现创建列表的方式不只一种。如果你不想让你列表中的元素被解释执行,记得引用(quote)一下。

=> (list "truck" "car" "bicycle" "plane") ;;创建一个列表 
   ("truck" "car" "bicycle" "plane")

;;与上面方式等价
=> '("truck" "car" "bicycle" "plane")
    ("truck" "car" "bicycle" "plane")

;;查看列表的类型
=>(class '("truck" "car" "bicycle" "plane"))
clojure.lang.PersistentList

;; 给创建的列表绑定一个全局变量 
=> (def vehicles (list "truck" "car" "bicycle" "plane"))
#'user/vehicles

;;查看是否是序列
=>(seq? vehicles)
true

;;查看是否是列表 
=>(list? vehicles)
true

;;查看是否是集合 
=> (coll? vehicles)
true

;;获取第一个元素
=>(first vehicles)
"truck"

;;获取第二个元素 
=>(second vehicles)
"car"

;;获取最后一个元素
=>(last vehicles)
"plane"

;;获取除第一个元素以外的剩下列表
=>(rest vehicles)
("car" "bicycle" "plane")

;;获取第n个元素
=>(nth vehicles 0)
"truck"

=>(nth vehicles 1)
"car"

;;添加元素 (这只是返回一个新的列表,vehicles 并不会被改变)
=> (conj vehicles "motorcycles")
("motorcycles" "truck" "car" "bicycle" "plane")


Cons

Cons是lisp语言中另一个类似列表的一种数据结构。术语”cons“意思就是构造一个对(pair),将这些对链接在一起然后形成一个类似列表的数据结构。就像list一样,cons既是一个类型,也是一个函数,我们可以使用cons来创建这种数据结构。


=>(cons "truck" (list "car" "bicycle" "plane"))
("truck" "car" "bicycle" "plane")

=>(class (cons "truck" (list "car" "bicycle" "plane")))
clojure.lang.Cons

=>(def vehicles (cons "truck" (list "car" "bicycle" "plane")))
#'user/vehicles

=>(seq? vehicles)
true

=>(list? vehicles)
false

=>(coll? vehicles)
true

=>(conj vehicles "motorcycle")
("motorcycle" "truck" "car" "bicycle" "plane")

=>(class (conj vehicles "motorcycle"))
clojure.lang.Cons

=>(cons "motorcycle" vehicles)
("motorcycle" "truck" "car" "bicycle" "plane")

=>(class (cons vehicles "motorcycle"))
clojure.lang.Cons

=>(conj "truck" nil)
java.lang.ClassCastException: cannot be cast to clojure.lang.IPersistentCollection

=>(cons "truck" nil)
("truck")

=>(class (cons "truck" nil))
clojure.lang.PersistentList

注意最后一个例子,是不是看起来很奇怪?当我们使用cons将一个元素附加到一个列表或者另一个cons结构上时,返回的仍然是一个cons类型结构。但是当我们将一个item附加nil上时,返回的却是list类型。这一点尤其注意。

向量

向量是除了list和cons之外的另一个很受欢迎的数据结构,因为它有时用起来有一些独特的优势。举个例子,因为向量使用方括号来表示,所以至少从视觉上来说会让它从大量的圆括号中脱颖而出,提供了更好的可读性。另外使用向量通常能提供比列表更好的性能优势。

=>(vector "truck" "car" "bicycle" "plane")
["truck" "car" "bicycle" "plane"]
;;一种简便的创建向量方式,这个不需要“引用”了哦
=>["truck" "car" "bicycle" "plane"]
["truck" "car" "bicycle" "plane"]

=>(class ["truck" "car" "bicycle" "plane"])
clojure.lang.PersistentVector

=>(def vehicles ["truck" "car" "bicycle" "plane"])
#'user/vehicles

=>(seq? vehicles)
false

=>(list? vehicles)
false

=>(vector? vehicles)
true

=>(coll? vehicles)
true
注意:虽然大多数函数对待向量和列表都会产生相同的结果,但有时候这种假设往往会引入一些问题。看下面例子,注意二者之间的区别:
=> (conj ["a" "b"] "c")
["a" "b" "c"]

=> (conj '("a" "b") "c")
("c" "a" "b")



转载于:https://my.oschina.net/clopopo/blog/144421

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值