lazy sequence
2018-06-11 21:18:26 0 举报
AI智能生成
clojure 惰性序列
作者其他创作
大纲/内容
有什么优点
提高性能
减少内存
特殊用处
读取文件
line-seq
读取数据结构
tree-seq
序列的原型函数
first
普通:返回第一个元素
lazy:调用了一个函数返回一个值和一个函数,再返回这个值
rest
普通:返回删除第一个元素的值
lazy
调用一个函数返回一个值和一个序列,返回这个序列
second
普通
返回序列的第二个值
lazy
使用rest返回一个函数,然后调用这个函数返回一个值和一个函数,返回这个函数?
nth
普通
返回从头部开始的第n个元素
lazy
执行一系列函数,并且返回最后一个的值
drop
普通
返回一个新的序列(将前n个元素去掉的)
lazy
执行一系列函数,并且返回最后一个函数
last
普通:返回序列中的最后一个元素
lazy
执行所有的序列函数,直到没有函数可以调用为止
take
普通
返回序列中的前n个元素
lazy
执行一些函数,并且将序列中的值全部返回
实际问题
为什么有时候要在for前面包装doall
因为如果有doall,在定义的时候每次里面的body都会执行一遍
否则根据惰性序列,可能会直接返回原来已经保存的值
值得怀疑
同一个作用域 如果要每次生效 才要用doall
参考
http://theatticlight.net/posts/Lazy-Sequences-in-Clojure/
为什么使用lazy sequence
因为这让不可能成为可能
让不可以实现的事情变得可以实现
到底是什么
一个逻辑或者算法上存在的序列
而不是非的内存中存在的序列
是clojure语言不可分割的一部分
clojure的序列包括lists,vectors和lazy sequences
特点
实际上并不算数据结构
算是一种object
So while calling first on a Clojure list, returns the item stored in the first cons cell in the list, calling the same on a lazy sequence instead calls a function which returns both a value and another function
怎么用
the good news
可以用于生成序列的原始函数
range
repeat
一个常数的循环序列
repeatedly
一个函数的循环输出
iterate
一个函数的循环输出,给定一个初始值,产生输出,再作为下一次的输入
但是记得千万不要直接调用
否则会耗光你的内存
clojure的大多数产生序列的函数产生的序列都是惰性的
map
remove
filter
take
drop
concat
(concat [1] [2] '(3 4) [5 6 7] #{9 10 8})
others
相互转化
lazy seq转为一般seq
doall
可以实现所有代码的执行
vector、list和apply等函数
基于cons cell 的序列转为lazy seq
什么是cons cell?
比如conj
user> (def foo (conj (lazy-seq [1 2 3]) 0))
#'user/foo
user> (type foo)
clojure.lang.Cons
#'user/foo
user> (type foo)
clojure.lang.Cons
user> (type (drop 1 foo))
clojure.lang.LazySeq
clojure.lang.LazySeq
这肯定是因为drop的原因
作者的这个例子就举得不对
map和first的实现有什么不同
0 条评论
下一页