common Lisp学习笔记(十二)

 

  • 12 Structure and The Type Syetem
    • 12.2 typep, type-of
    • 12.3 defining structures
    • 12.5 accessing, modifying structs
    • 12.6 kwargs to constructor functions
    • 12.7 修改结构体定义
    • 12.8 print func for structs
    • 12.9 equality of structs
    • 12.10 inheritance

12 Structure and The Type Syetem

总结一下前面学习过的lisp的基本类型,有number, symbol, cons, string, function, stream等,这些都是最基本的 数据类型. structures结构体是用户定义的数据类型,与其他语言类似

12.2 typep, type-of

(typep 3 'number) -> t
(typep 3 'integer) -> t
(typep 'foo 'symbol) -> t(type-of 'foo) -> symbol
(type-of '3.5) -> short-float

typep, type-of的用法都很简单。在lisp中,有以下规则

  • 所有的对象都继承于t,即都是t的子类型
  • NULL类型只包含符号nil
  • list类型包含cons和null, null是symbol和list的子类型

12.3 defining structures

defstruct macro定义新的结构体的名字和变量的默认值

(defstruct starship(name nil)(speed 0)(condition 'green)(shields 'down)

starship是结构体的名字,里面有4个成员变量,每个成员变量和初始值放在一个小括号中

使用defstruct定义好结构体之后,会自动定义一个make函数可以用来构造一个结构体,如make-starship

> (setf s1 (make-starship))
#S(starship name nilspeed 0condition greenshields down)

输出的结构体前面有#S表示,也可以直接用#S结构体对变量进行赋值

> (setf s2 '#s(starship speed (warp 3)))
#S(starship ...)

defstruct之后还会自动生成starship-p这个predicate,可以判断对象是否是这个类型

12.5 accessing, modifying structs

定义结构体之后,使用structname-member可以访问成员变量,如(starship-speed s2) -> (warp 3)

对structname-member可以使用setf赋值

12.6 kwargs to constructor functions

defstruct里面定义的是成员变量的默认值,我们在构造一个新对象的时候可以使用关键字参数来设置成员变量的初始 值,回顾前面使用关键字参数要在前面加上冒号

> (setf s3 (make-starship :name "Jack":shields 'damaged))
#S(starship name "Jack"...)

12.7 修改结构体定义

使用defstruct定义好结构体之后,如果再次定义同名的结构体,会对之前已经创建好的实例造成无法预测的影响 可以重新使用make-structname构造函数来修改实例的值

ex 12.4

(defstruct node (name)(question)(yes-case)(no-case))(setf *node-list* nil)(defun init () (setf *node-list* nil))(defun add-node (name question yes-case no-case) (push (make-node :name name :question question :yes-case yes-case :no-case no-case) *node-list*)name)(defun find-node (name)(find-if #'(lambda (e) (equal name (node-name e))) *node-list*))(add-node 'start"Does the engine turn over?"'engine-turns-over'engine-wont-turn-over)
(add-node 'engine-turns-over"Will the engine run for any period of time?"'engine-will-run-briefly'engine-wont-run)
(add-node 'engine-wont-run"Is there gas in the tank?"'gas-in-tank"Fill the tank and try starting the engine again.")
(add-node 'engine-wont-turn-over"Do you hear any sound when you turn the key?"'sound-when-turn-key'no-sound-when-turn-key)
(add-node 'no-sound-when-turn-key"Is the battery voltage low?""Replace the battery"'battery-voltage-ok)
(add-node 'battery-voltage-ok"Are the battery cables dirty or loose?""Clean the cables and tighten the connections."'battery-cables-good)(defun process-node (name)(let ((node-exist (find-node name)))(if node-exist (if (y-or-n-p "~&~A " (node-question node-exist))(node-yes-case node-exist)(node-no-case node-exist))(format t "~&node ~S not yet defined." name))))(defun run ()(do ((current-node 'start (process-node current-node)))((null current-node) nil)(when (stringp current-node) (format t "~&~S" current-node) (return nil)))))(defun prompt-for (s)(format t "~&~A~%" s)(read))(defun interactive-add ()(let* ((name (prompt-for "node name?"))(question (prompt-for "question?"))(yes-action (prompt-for "if yes?"))(no-action (prompt-for "if no?")))(add-node name question yes-action no-action)))

12.8 print func for structs

默认输出一个结构体的时候,会把整个结构体的所有成员都输出,但是有时我们只需要其中一些信息,因此可以通过修改结构体的输出函数来实现

clisp中一个简化输出的结构体习惯用"#<...>"来表示,如#<starship enterprise>

下面重新定义输出的函数,里面要有三个参数,要输出的结构体,输出的stream,还有输出的深度限制。输出到屏幕则stream为t,深度暂时不做讨论。如只需要输出starship的name

(defun print-starship (x stream depth)(format stream "#<starship ~A>" (starship-name x)))

重新定义结构体,使用:print-function参数

(defstruct (starship (:print-function print-starship))(captain nil)(name nil)(shields 'down)(condition 'green)(speed 0))> (setf s4 (make-starship :name "hello"))
#<starship hello>

注意上面的括号,starship左边的括号在print-starship之后已经闭合,后面参数还是一样

重新定义输出还有一个作用,比如一些结构体中包含另一个结构体,而另一个结构体也反过来包含这个结构体,比如一个船长拥有一艘船,一艘船则属于一个船长,类似于一些数据库,这种情况下普通的输出会形成无限的循环。

ex 12.5

(defstruct starship (captain nil) (name nil) (speed 0) (condition 'green) (shields 'down))(defstruct (captain (:print-function print-captain))nameageship)
(defun print-captain (x stream depth) (format t "#<captain ~A>" (captain-name x)))(setf s1 (make-starship :name "Enterprise"))
(setf c1 (make-captain :name "James T.Kirk" :age 35 :ship s1))
(setf (starship-captain s1) c1)

12.9 equality of structs

之前equal函数只要两个对象的值相等就会返回t,但是对于结构体比较特殊,即使两个结构体的成员的值完全相同,equal函数也会返回nil,只有比较同一个结构体对象的时候,才会返回t

如果要比较两个结构体的值相等,可以使用equalp,eg

(setf s1 (make-starship))
(setf s2 (make-starship))> (equalp s1 s2)
t

equalp函数还有一点与equal不同,就是比较两个字符串的时候是忽略大小写的

(equal "hello" "Hello") -> nil
(equalp "hello" "Hello") -> t

12.10 inheritance

lisp的结构体和其他语言一样,也可以继承于基类,继承时加上关键字:include,类似于重定义输出函数的用法

(defstruct ship(name nil)(captain nil)(crew-size nil))(defstruct (starship (:include ship))(weapons nil)(shields nil))(defstruct (supply-ship (:include ship))(cargo nil))

在子类中可以用同样的方法来反问基类的成员变量

转载于:https://www.cnblogs.com/jolin123/p/4531467.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/297318.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

于明:APU能否接力取代迟暮的X86?

图&#xff1a;AMD Fusion APU中国发布会 有作用力必然有反作用力&#xff0c;有光亮也必然有黑暗&#xff0c;有诚实也必然有欺骗&#xff0c;任何事物都具有两面性&#xff0c;而PC的核心处理器也不例外&#xff0c;存在着“真融合”与“假融合”之分。 就拿AMD(NYSE: AMD)在…

SQL Azure Reporting CTP

http://blogs.msdn.com/b/azchina/archive/2011/02/18/sql-azure-reporting-limited-ctp-arrived.a概念SQL Azure Reporting 把云端报表作为服务来提供&#xff0c;构建于SQL Server Reporting Services 和 SQL Azure 技术之上。诸如SQL Azure Reporting此类云端报表服务具有许…

Windows 11 小技巧- winget安装和维护应用程序

安装好Windows 11后&#xff0c;你可能需要为系统安装常⽤的⼯具&#xff0c;例如安装Visual Studio Code&#xff0c;Google Chrome &#xff0c;VLC Player 等应⽤。以往你可能需要⾃⼰去各大网站上安装。如果你曾经使⽤Linux, 你可以通过命令⾏⽅式用apt安装和维护很多的…

经典语句,看看让心灵宁静

1.哈佛有一个着名的理论&#xff1a;人的差别在于业余时间&#xff0c;而一个人的命运决定于晚上8点到10点之间。每晚抽出2个小时的时间用来阅读、进修、思考或参加有意的演讲、讨论&#xff0c;你会发现&#xff0c;你的人生正在发生改变&#xff0c;坚持数年之后&#xff0c;…

输出毫秒_自学单片机第十三篇上:单点输出

关注一下&#xff0c;更多精彩等着你&#xff01;打开之前的工程&#xff0c;当然新建也可以&#xff0c;具体步骤看之前的文章就行。因为是学习&#xff0c;所以也用不着总是新建工程&#xff0c;起名起一大堆&#xff0c;接下来&#xff0c;除非要用两个执行文件&#xff0c;…

python有类似spring_python有类似spring_Python的Spring与J的Spring相比

依赖注入框架在动态类型语言中几乎没有那么有用。例如&#xff0c;请参见Java中的表示Dependency Injection: Vitally important or totally irrelevant?依赖注入框架提供的灵活性是至关重要的&#xff0c;而在Python中&#xff0c;这通常会导致不必要的复杂性。这并不意味着原…

Hadoop分布式文件系统:架构和设计要点

一、前提和设计目标 1、硬件错误是常态&#xff0c;而非异常情况&#xff0c;HDFS可能是有成百上千的server组成&#xff0c;任何一个组件都有可能一直失效&#xff0c;因此错误检测和快速、自动的恢复是HDFS的核心架构目标。 2、跑在HDFS上的应用与一般的应用不同&#xff0c;…

22张令人叹为观止的照片,你所未知的另一面

全世界只有3.14 % 的人关注了爆炸吧知识见惯了身边的平淡和琐碎&#xff0c;总要开阔眼界&#xff0c;长长见识。走&#xff0c;带你看震惊世界的22张照片&#xff0c;保准惊呆你&#xff01;1、你知道他们是如何安装那些巨大的电线塔的了吧&#xff1a;2、人体分离魔术&#x…

C#备份数据和还原数据

private void button1_Click(object sender, EventArgs e) {//选择要备份的路径 this.folderBrowserDialog1.ShowDialog();this.txtDbBackup.Text folderBrowserDialog1.SelectedPath; }private void btnChooseOK_Click(object sender, EventArgs e)…

Windows 11 小技巧- WSL运行本地GPU算力

WSL 已经被很多开发⼈员⽤于云原⽣开发&#xff0c;但如果你像我每天要完成⼈⼯智能应⽤的 发&#xff0c;会⼀直希望能加上GPU算⼒&#xff0c;这样就不需要再去安装⼀台Linux的机器去做⼈⼯智能的⼯作了(毕竟很多的⼈⼯智能场景都是在Linux下完成的)。这次Windows 11 不仅⽀…

python pdf 图片_第一节:python提取PDF文档中的图片

1、安装第三方类库pymupdf&#xff1a;pip install pymupdf2、安装完成后直接上代码&#xff0c;代码如下&#xff1a;import fitzimport timeimport reimport osdef pdf2pic(path, pic_path):t0 time.clock() # 生成图片初始时间checkXO r"/Type(? */XObject)" #…

利用两款软件实现图片转文字

wps&#xff08;另存为pdf&#xff09;CajViewer&#xff08;文字识别&#xff09;图片识别技术&#xff0c;网上看到的教程&#xff0c;真是佩服&#xff01;转载于:https://blog.51cto.com/p6xos/1655695

私房钱就藏在老婆眼皮底下

1 建议出一个藏私房钱的教程▼2 以前还是打飞的就这个价格&#xff0c;最多是个飞公交▼3 众所周知狗是不会剪视频的&#xff0c;所以是真的▼4 老实讲我小时候也幻想过这个操作▼5 这可真是一个悲伤的故事▼6 这可真是令人羡慕的发量▼7 退一步越想越气忍一时越想越亏▼…

19.Silverlight调用webservice上传多个文件

Silverlight不支持读写服务器端的硬盘&#xff0c;可是很多时候用户需要在Silverlight客户端往服务器端上传文件&#xff0c;那么本节将讲述 Silverlight中最简单的上传文件的方式&#xff1a;在Silverlight客户端将文件序列化为Byte[]字符组&#xff0c;然后服务器端使用 webS…

python第k序列元素查找_Python寻找第k小的元素

更多: http://my.oschina.net/u/438371/blog/1319561.[代码][Python]代码# -*- coding: utf-8 -*-from random import randintfrom math import ceil, floordef _partition(A, l, r, i):"""以A[i]为主元划分数组A[l..r]&#xff0c;使得&#xff1a;A[l..m-1] &…

原创:PHP内核研究:HASH表和变量

PHP HASH表 在PHP中,所有的数据 无论变量,常量,类,属性 都用Hash表来实现. 先要说说 HASH表 [c]typedef struct bucket { ulong h; /* Used for numeric indexing */ uint nKeyLength; //key长度 void *p…

Windows 11 小技巧- 安装

Windows 11 依赖于TPM 2.0&#xff0c;什么是TPM呢?TPM技术旨在提供基于硬件的与安全性相关的功能。TPM芯片是⼀个安全的加密处理器&#xff0c;有助于执⾏⽣成、存储和限制加密密钥的使用等操作。TPM芯片包含多重物理安全机制&#xff0c;具有防篡改功能&#xff0c;恶意软件…

如何判断一个人是不是值得深入交流?

全世界只有3.14 % 的人关注了爆炸吧知识每次翻看刚加好友的朋友圈时&#xff0c;都会对 ta 产生直观的判断。如果朋友圈很丰富&#xff0c;往往会觉得 ta 很有趣&#xff0c;会迫切想要和 ta 链接&#xff0c;而看到某些很单调的朋友圈&#xff0c;根本就没有深入沟通的欲望。真…

python 逆向生成正则表达式_用Python中的正则表达式生成lis

我有一个小脚本&#xff0c;用来产生一个预定义的字体和文本图像。我想将其更改为使用多种字体来呈现相同的文本&#xff0c;例如字母A以5种字体呈现。我将我的字体列表定义为&#xff1a;fonts [ Georgia, Consolas, Arial]然后我把它用在&#xff1a;for item in enumerate(…

Restive.js – 轻松让网站变成响应式和自适应

Restive.js 是一个 jQuery 插件&#xff0c;可以帮助您轻松快捷地添加响应式功能到你网站&#xff0c;适应几乎所有拥有 Web 功能的设备。使用设备检测&#xff0c;高级管理断点&#xff0c;以及方向管理的组合&#xff0c;Restive.js 会给你的网站提供一种不可思议的能力。 在…