Lisp学习5
来源:互联网 发布:1元域名注册 编辑:程序博客网 时间:2024/06/14 08:19
如果你特定想要重设由 DEFVAR 定义的变量,要么使用 SETF直接设置它,要么使用 MAKUNBOUND 先将其变成未绑定的,再重新求值 DEFVAR 形式。
在用 DEFVAR 和 DEFPARAMETER 定义一个变量之后,就可以从任何一个地方引用它。
如:(defun increment-widget-count () (incf *count*))
如果想要临时重定义全局变量(如:*standard-output*),只需要将其重新绑定即可,比如可以用 LET :
(let ((*standard-output* *some-other-stream*))
(stuff))
* 在任何由于调用 stuff 而运行的代码中,对 *standard-output* 的引用将使用由 LET 所创建的绑定,并且当 stuff 返回并且程序控制离开 LET 时,这个对 *standard-output* 的新绑定就随之消失,接下来对 *standard-output* 的引用将回到 LET 之前的绑定。(在任何给定时刻,最近建立的绑定会覆盖所有其他的绑定)
一个简单的例子:
(defvar *x* 10)
(defun foo () (format t "x: ~d~%" *x*))
CL-USER> (foo)
x: 10
NIL
CL-USER> (let ((*x* 20)) (foo))
x: 20
NIL
CL-USER> (foo)
x: 10
NIL
(defun bar ()
(foo)
(let ((*x* 20)) (foo))
(foo))
CL-USER> (bar)
x: 10
x: 20
x: 10
NIL
常量:
所有的常量都是全局的,并且使用 DEFCONSTANT 定义:
(defconstant name initial-value-form [documentation-string])
与 DEFVAR 和 DEFPARAMETER 相似, DEFCONSTANT 在所使用的名字上产生了全局效果——从此该名字仅被用于指向常量,它不能被用作函数形参或是任何其他的绑定形式进行重绑定。
一般用 +constant-variable-name+ 的形式来表示常量
赋值:
为绑定赋予新值需要使用 SETF 宏—— Common Lisp 的通用赋值操作符,其基本形式为:
(setf place value)
如:
(setf x 10) ; 将值 10 赋给变量 x
为一个绑定赋予新值对该变量的任何其他绑定没有效果,并且它对赋值之前绑定上所保存的值也没有任何效果。
SETF 也可用于依次对多个位置赋值。
如:
(setf x 1)
(setf y 2)
可以写成:
(setf x 1 y 2)
SETF 返回最近被赋予的值,因此也可以像下面的表达式那样嵌套调用 SETF ,将 x 和 y 赋予同一个随机值:
(setf x (setf y (random 10)))
广义赋值:
Simple variable: (setf x 10)
Array: (setf (aref a 0) 10)
Hash table: (setf (gethash 'key hash) 10)
Slot named 'field': (setf (field o) 10)
* AREF 是数组访问函数,GETHASH 做哈希表查找。
其他修改位置的方式:
(incf x) ≡ (setf x (+ x 1))
(decf x) ≡ (setf x (- x 1))
(incf x 10) ≡ (setf x (+ x 10))
* 类似 INCF 和 DECF 这种宏称为 修改宏(modify macro)
ROTATEF:
在位置之间轮换他们的值:
(rotatef a b) ; 将交换两个变量的值并返回NIL
* 等价于(let ((tmp a)) (setf a b b tmp) nil)
SHIFTF:
它将值向左侧移动而不轮换它们:
(shiftf a b 10) ; 将 b 的值赋给 a ,将 10 赋值给 b
* 等价于(let ((tmp a)) (setf a b b 10) tmp)
**宏:标准控制构造
WHEN 和 UNLESS:
* 特殊操作符 PROGN 可以按顺序执行任意数量的形式并返回最后一个形式的值。
(if (spam-p current-message)
(progn
(file-in-spam-folder current-message)
(update-spam-database current-message)))
等价于:
(when (spam-p current-message)
(file-in-spam-folder current-message)
(update-spam-database current-message))
* 如果 WHEN 没有被内置到标准库中,可以像下面这样用一个宏来自己定义 WHEN:
(defmacro when (condition &rest body)
`(if ,condition (progn ,@body)))
与 WHEN 宏同一个系列的另一个宏是 UNLESS, 它取相反的条件,只有当条件为假时才求值其形式体,相当于:
(defmacro unless (condition &rest body)
`(if (not ,condition) (progn ,@body)))
COND:
用于表达多重分支条件的宏 COND,它的基本结构:
(cond
(test-1 form*)
.
.
.
(test-N form*))
主体中的每个元素都代表一个条件分支,并由一个列表所构成,列表中含有一个条件形式,以及零或多个当该分支被选择时将被求值的形式。
习惯上,那个用来表示 if/else-if 链中最后一个 else 子句的分支将被写成带有条件T。虽然任何非 NIL 的值都可以使用,但在阅读代码时, T 标记确实有用。
如:
(cond (a (do-x))
(b (do-y))
(t (do-z)))
AND、OR 和 NOT(布尔逻辑操作符):
NOT:
接受单一参数并对其真值取反,当参数为 NIL 时返回 T,否则返回 NIL。
AND 和 OR 则是宏:
实现了对任意数量子表达式的逻辑合取和析取操作,并被定义成宏以便支持“短路”特性。
如:
(not nil) → T
(not (= 1 1)) → NIL
(and (= 1 2) (= 3 3)) → NIL
(or (= 1 2) (= 3 3)) → T
循环:
DOLIST:
在一个列表的元素上循环操作,使用一个依次持有列表中所有后继元素的变量来执行循环体。
形如:
(dolist (var list-form) body-form*)
例如:
CL-USER> (dolist (x '(1 2 3)) (print x))
1
2
3
NIL
在这种方式下,DOLIST 这种形式本身求值为 NIL
如果想在列表结束之前中断一个 DOLIST 循环,则可以使用 RETURN
CL-USER> (dolist (x '(1 2 3)) (print x) (if (evenp x)(return)))
1
2
NIL
DOTIMES:
用于循环计数的高级循环构造,形如:
(dotimes (var count-form) body-form*)
其中的 count-form 必须要能求值为一个整数。通过每次循环,var 所持有的整数依次为从 0 到比那个数小 1 的每一个后继整数。
如:
CL-USER> (dotimes (i 4) (print i))
0
1
2
3
NIL
小应用(输出9*9乘法表): (dotimes (i 9) (dotimes (j 9) (format t "~3d * ~d = ~3d " (+ 1 i) (+ 1 j) (* (+ 1 i) (+ 1 j)))) (format t "~%"))
- Lisp学习5
- lisp学习
- 学习lisp
- LISP学习
- Common Lisp 学习之路(5)
- lisp学习 耶!
- Common Lisp的学习
- lisp学习笔记
- common lisp 学习笔记
- Lisp 学习资料
- Lisp 学习日志
- lisp学习资料索引
- 学习COMMON LISP总结
- Common Lisp 学习书目
- lisp-Scheme学习笔记
- Common Lisp 学习笔记
- Lisp学习1
- Lisp学习2
- 使用Packet.dll和npf.sys实现原始数据包的发送和接收
- 机器学习中的数学(1)-回归(regression)、梯度下降(gradient descent)
- leetcode_94_Binary Tree Inorder Traversal
- HDU 2044 一只小蜜蜂
- AngularJS $on、$emit和$broadcast简单功能实例
- Lisp学习5
- Mac OS X Yosemite安装Hadoop 2.6记录
- C++开源项目
- hdu4549---M斐波那契数列(矩阵+欧拉定理)
- c++ string 类基本用法
- ZOJ 2107 HDU 1007 Quoit Design(最近点对)
- 场景loadiing
- 机器学习中的数学(2)-线性回归,偏差、方差权衡
- hdu 4374 单调队列