Common-Lisp常用函数速查速记笔记
这是一本Common-lisp常用函数和宏查询手册,将持续更新。当然如果你有英文阅读能力,我还是建议你手中常备一本CookBook。
列表操作
list 生成列表
生成列表。
|
|
cons 构造列表
把两个列表构造成一个列表。
|
|
car 获取列表中的第一个元素
|
|
cdr 获取第一元素后面的所有元素
|
|
copy-list
建立一个列表的拷贝。注意是新建cons而不是之前原来的列表对象。
|
|
make-list
关键字参数来构建一个任意长度的元素的列表。
|
|
nth 获取列表中的car指针(0索引)
获取列表中某个索引的元素。
|
|
nthcdr 获取列表中的cdr指针(0索引)
获取列表中某个元素后面的其他元素构成的列表。
|
|
subseq 截取列表
根据开始和结束索引截取列表的子列表。
reverse 反转列表
|
|
sort 排序
适应自定义的函数对列表进行排序。注意这个是函数是产生副作用的。所以为了保护数据,可以使用(copy-list)对原来的数据进行保护
|
|
remove 不含元素的新列表
举例来说,函数 remove 接受一个对象和一个列表,返回不含这个对象的新列表
注意原理的列表并没有发生任何的改变
逻辑操作
if
(if [逻辑表达式] [表达式1] [表达式2]) 逻辑表达式为真 求值表达式1 否则求值表达式2
|
|
其中listp 是判断一个元素是不是列表。
and
输入一组表达式。如果所有都为真,那么返回最后一个表达式的值。否则返回nil;
|
|
or
值返回第一个值位真的表达式的值。
|
|
循环操作
do (do-while循环)
循环语句 (do (参数列表) (退出条件 退出返回) (循环求值表达式));
参数列表(变量名 初始化值 变量更新方式)
|
|
dolist
循环一个列表(用法类似其他语言中的foreach)
|
|
函数
apply
调用一个函数求值并返回。参数作为列表传入。
|
|
funcall
调用一个函数求值并返回。参数不需要使用列表包裹。
|
|
lambda
用于生成一个匿名函数。相当于返回了函数名。
|
|
mapcar (映射函数)
把列表中每个个car指针送到函数中求值,然后返回值构成新的列表。
|
|
maplist
把列表中每个个car指针送到函数中求值,然后返回值构成新的列表。
|
|
其他
progn
对一组表达式,依次求值,并且返回最后一个表达式的值。
集合操作
member 返回符合条件的列表(集合)中的元素
返回一个列表中符合要求的元素之后的列表。其中条件可以进行自定义。也可以对列表中元素进行自定义。
|
|
member-if 返回任意一个要求函数的元素后面的列表
其中条件是一个函数这个函数是自定义的。
|
|
adjoin
接受一个元素和一个列表。如果这个元素不存在在列表中在加入到列表中。
|
|
union 并集
intersection 交集
set-difference 补集
栈
push 压栈
pop 出栈
pushnew 只进新元素的压栈
数学
oddp
判断一个数字是不是奇数。是返回T 否则返回NIL
输入输出
read 输入(PS:这里更像是等待输入)
记住 read 会一直永远等在这里,直到你输入了某些东西,并且(通常要)按下回车。因此,不打印明确的提示信息是很不明智的,程序会给人已经死机的印象,但其实它是在等待输入。
第二件关于 read 所需要知道的事是,它很强大: read 是一个完整的 Lisp 解析器(parser)。不仅是可以读入字符,然后当作字符串返回它们。它解析它所读入的东西,并返回产生出来的 Lisp 对象
format 输出
|
|
其中 ~A
是占位符 ~%
是换行符。最会返回NIL而不是T。NIL
不代表着打印失败了。打印是程序的副作用和取值无关。
变量
let 局部变量
PS. 我敢打包票js中的关键字是灵感来源于此。
defparameter 全局变量
|
|
defconstant 全局常量
|
|
boundp 检查一个符号是否是全局的变量或者常量
|
|
typep 变量类型判断
特殊的数据结构
数组操作
make-array 创建数组
|
|
上面的代码可以创建一个2X3的数组。其中使用了关键字参数。表示初始化所有的值都是nil
aref 取出数组中的位置的值(0索引的)
|
|
这里就可以把数组里(0,0)的位置赋值为B了,但是注意这里是赋值成了符号’B,不是字符串“B”哦。
表示字面常量的数组
一般来说使用#na
的语法来表,比如:#2a((a b c) (nil nil nil))
如果全局变量 *print-array*
为真,则数组会展示成这种形式。
vector 和 svref 向量操作
一维的数组表示为向量,生成时直接传参数就可以了。读取和数组是一样的0索引。
字符串
字符串就是字符构成的数组
char-code code-char 字符串的ASCII转换
char
取字符串的第n个字符
字符串的比较
- sring-equal 不区分大写写的比较
- equal 区分大小写的比较
结构体
defstruct 定义结构体
|
|
这个方法是定义了一个结构体。同时隐式的定义了一些方法:
- make-point
- point-p
- copy-point
- point-x
- point-y
输入输出流
路径名 make-pathname
路径名(pathname)是一种指定一个文件的可移植方式。路径名包含了六个部分:host、device、directory、name、type 及 version。你可以通过调用 make-pathname 搭配一个或多个对应的关键字参数来产生一个路径。在最简单的情况下,你可以只指明名字,让其他的部分留为缺省:
open 打开一个文件流
open可以接受一个上面那样的标准路径名数据,之后打开一个文件流。在创建这流的时候,可以使用
关键字参数来指定流的行为。比如读写或者是读写都做。还可以指定在缺省条件下的行为。
比如我们现在建立一个新建文件的输出流。他是这样的。
read-line 读取流中的一行
少废话上代码:
with-open-file (打开文件宏)
打开操作一起哈成
|
|
包定义
|
|
这里主要是在export是你要 分享出去的包。
类型转化
float 将任何实数转换成浮点型
|
|
truncate 返回任何实数的整数部分
|
|
floor 向下取整
ceiling 向上取整
round 四舍五入
mod 取余数
signum 符号函数
abs 绝对值函数
random 随机数
expt 指数
|
|
宏相关
defmacro 宏定义
下面有具体的例子
` 和 , 和 ,@
少废话看代码。
|
|
那么这样的好处是什么?看看我们自己定义一个while函数。
|
|
gensym 返回一个独一无二的符号
在宏的定义的时候为什么要使用这个函数呢?
那是因为在使用内部的变量的时候会出现,外面的定义个宏内部定义一样导致变量被入侵的情况。
于是在写宏的时候就要考虑得和程序设计人员一样。
除此之外还有就是 传入的表达式很肯能导致变量被多重取值了。这是很恐怖的。
这里有一个把一段代码取值n次的宏定义。注意体会他的脊髓。
|
|
注意这没有反引号的生成的新符号保证了在,反引号里面的h并不在被重新求值了。
这个是很重要的。在宏的设计里面。