Common lisp 指示符的性质是什么?
Svante在另一个答案中显示了字符串指示符,这让我大吃一惊。请执行以下操作:Common lisp 指示符的性质是什么?,common-lisp,Common Lisp,Svante在另一个答案中显示了字符串指示符,这让我大吃一惊。请执行以下操作: (string= :& "&") -> T 看着CLH,他们说,指示器是一个表示另一个对象的对象。这很好,但由于这些是不同的对象,需要在某个地方进行某种强制。我的意思是,如果一个“非零原子”可以满足下面的列表指示符,那么在某个地方就存在处理这个问题的逻辑 列表指示符。对象列表的指示符;就是一个 表示一个列表的对象,它是:一个非零原子 (表示元素为非零原子的单态列表)或 适当的列表(表示其本身)
(string= :& "&") -> T
看着CLH,他们说,指示器是一个表示另一个对象的对象。
这很好,但由于这些是不同的对象,需要在某个地方进行某种强制。我的意思是,如果一个“非零原子”可以满足下面的列表指示符,那么在某个地方就存在处理这个问题的逻辑
列表指示符。对象列表的指示符;就是一个
表示一个列表的对象,它是:一个非零原子
(表示元素为非零原子的单态列表)或
适当的列表(表示其本身)
我认为指示符可以是一个概念,例如泛型函数。。但是下面这行来自CLHS
除非另有说明,在表示的对象
可能被多次使用,这取决于实现是否
对象仅被强制一次,或者无论强制是否每次发生
必须使用对象的时间
。。。这样看起来很具体
所以我的问题是
- 如何在实现中实现指示符的示例是什么
- 用户是否可以以任何方式扩展此机制
- 这种机制在不同的指示器之间是一致的吗?(在clhs中,似乎有18种指示符)
字符
代替字符串
,因为它表示一个字符字符串
如何:系统级
实现的方式有所不同,请查看它们各自的源代码。
您可以在下面找到使用级别代码之类的内容
(defun human-address (human)
(etypecase human
(human ...)
(string (human-address (gethash human *humanity*)))))
甚至
(defun human-address (human)
(when (stringp human)
(setq human (gethash human *humanity*)))
(unless (human-p human)
(error ...))
...)
如果defgeneric
由于引导问题而不可用,或者作为优化被避免
如何:用户级
系统级指示符不是用户可扩展的。
也就是说,您不能定义自己的包或字符串指示符
但是,您可以为自己的类型定义自己的标识符,例如:
(defclass human ...)
(defvar *humanity* (make-hash-table ...))
(defgeneric human-address (human)
(:method ((human human))
...)
(:method ((name string))
(human-address (gethash name *humanity*))))
这里,
字符串
用作人类
的指示符。指示符只不过是一个表示另一个对象的对象。他们的语言没有什么特别之处;指示符的概念只是使某些编程实践更容易的一个概念。词汇表上说:
n。表示另一个对象的对象。在
如果参数被描述为
一个类型的指示符,运算符的描述写在
假设对该类型的适当强制已经发生的方式
发生;也就是说,参数已经是所表示的类型。
有关详细信息,请参阅
该部分的链接非常有用:
指示符是表示另一个对象的对象
如果运算符的参数被描述为指示符,则
操作员描述的编写方式假定
参数的值是表示的对象;就是
参数已为所指示的类型。(a)项目的具体性质
对象由“«类型»指示符”或“指定对象的指示符”表示
«类型»可在“«类型»指示器”的词汇表条目中找到。)
能够在词汇表中查找有帮助的内容。例如,字符串指示符可以代表字符串:
n。字符串的指示符;就是一个
对象,该对象表示一个字符串,并且是以下内容之一:字符(表示
将字符作为其唯一元素的单例字符串)
符号(表示作为其名称的字符串)或字符串(表示
本身)。其目的是使该术语与行为一致
弦的长度;扩展字符串的实现必须扩展字符串的含义
以兼容的方式使用该术语
该标准还定义了获取由字符串指示符指定的字符串的函数:
(defun make-person (name)
"Return a person with the name designated by NAME."
(list :name (string name)))
(defun person-name (person)
"Return the name of a person (a string)."
(getf person :name))
返回由x描述的字符串;具体而言:
- 如果x是字符串,则返回它
- 如果x是一个符号,则返回其名称
- 如果x是一个字符,则返回包含该字符的字符串。字符串可能执行附加的、由实现定义的操作 转换
(defun make-person (name)
"Return a person with the name designated by NAME."
(list :name (string name)))
(defun person-name (person)
"Return the name of a person (a string)."
(getf person :name))
指示符的概念只是一种编程约定,它使定义灵活的API变得更容易。CommonLisp被定义为一种语言来统一一组现有的Lisp,它可能是统一不同实现行为的更简单的方法之一
有一个列表指示符的概念在
n。对象列表的指示符;就是,
一个表示一个列表的对象,它是一个非零原子
(表示元素为非零原子的单态列表)或
适当的列表(表示其本身)
keyform{normal子句}*[否则子句]=>结果*
普通子句::=(键形式*)
键—对象列表的指示符。在本案中,
符号t和其他符号不得用作钥匙指示器。到
将这些符号本身称为键、指示符(t)和
(否则)必须分别使用
我不知道有哪个函数可以返回由列表指示符指定的列表,但它很容易编写(这不会处理t和的特殊行为,否则即大小写(defmacro deftransform (name &rest args)
`(setf (gethash ',name *transforms*)
(make-transform ,@args)))
(defmacro deftransform (name &rest args)
(setf (get ',name 'transform) (make-transform ,@args)))
(defun transform (x)
(if (transformp x) x
(gethash name *transforms*)))
(defun transform (x)
(if (transformp x) x
(get x 'transform)))