首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用途/功能点“符号-名称”?

用途/功能点“符号-名称”?
EN

Stack Overflow用户
提问于 2019-10-13 17:19:41
回答 5查看 155关注 0票数 0

乍一看,有一个函数返回符号的名称似乎有点傻,必须使用同一符号的名称来调用该名称。也就是说,在调用上下文中,函数返回的内容应该是显而易见的。另一方面,identity有时是有用的(我刚才忘记了在哪里),但我认为(也许是错误的) symbol-function存在的原因不仅仅是作为一种身份。

然而,超石化提供了一个可能的提示:

代码语言:javascript
运行
复制
 (symbol-name 'temp) =>  "TEMP" 
 (symbol-name :start) =>  "START"
 (symbol-name (gensym)) =>  "G1234" ;for example

我注意到,:start的意思是从关键字包中获取符号start的名称,其中关键字包仅由:表示。(:keyword是它的较长的形式,没有必要使用)。因此,在本例中,symbol-name起着简单删除包前缀的作用。

它可能做的另一件事是,如果一个实现不区分大小写,它将通过删除所提供的符号名中的大小写来获得实际名称。

这是粗略的,还是对我缺少的这个功能有什么重要意义?

关于符号(现在澄清了),有一件事让我感到困惑,那就是symbol-plist并没有告诉您符号的所有信息(比如,它是否持有一个特殊变量或函数的值)。相反,plist是一个主要的遗留特性,现在主要被散列表所取代。因此,即使在符号上设置了一个特殊变量,对symbol-plist的调用也会返回NIL

关于这一点的最后一个问题,Paul在第8章(p133)中说,“你可以使用符号作为数据对象和事物的名称,而不了解两者之间的关系”。正确的说法是,如果我们现在很少使用plist,那么今天,我们通常根本不使用符号“作为数据对象”,相反,只是作为的名称(当然,它与CL中的二元性相同,即symbol-functionsymbol-value同时使用)。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2019-10-18 12:25:30

让我们假设您想要编写一些协议,用于在两个不同的系统之间通过某种串行通道传输结构比特。

代码语言:javascript
运行
复制
(defgeneric transmit-object (o stream))

符号的处理方法是什么?

代码语言:javascript
运行
复制
(defmethod transmit-object ((o symbol) stream)
  ... (symbol-name o) ...)

特别是,在需要对符号进行推理的时候,您肯定不知道符号的名称,而且如果不使用symbol-name,您就无法编写这样的协议(或者某些绝对骇人听闻的黑客,比如将符号打印成字符串并使用该协议)。

对于symbol-plist,实现完全可以将各种信息保存在符号的属性列表中。我甚至不确定是否不允许实现(更聪明的版本):

代码语言:javascript
运行
复制
(defun symbol-value (s)
  (let* ((d (load-time-value (cons nil nil)))
         (v (get s secret-value-indicator d)))
    (when (eq v d)
      (error ...))
    v))

也许这是不允许的,但我不确定。当然,用这种方式保存函数定义曾经是相当常见的。

票数 1
EN

Stack Overflow用户

发布于 2019-10-13 20:42:06

符号是物体。您可以创建它们并以编程方式传递它们。这些对象的属性之一是它们的名称,即字符串。Symbol-name是它的读取器(而不是访问器)。就这样。

在代码的表示中也使用符号。在本例中,它们由读取器创建并由编译器使用。然而,这并不是它们唯一的用途,而且规范也没有这样的假设。我希望这能解决你问题的核心。

下面是一个函数,给定一个符号,它返回一个被嵌入在同一个包中的符号,但它的名称是相反的:

代码语言:javascript
运行
复制
(defun reverse-symbol (symbol)
  (intern (make-symbol (reverse (symbol-name symbol)))
          (symbol-package symbol)))

下面是一个函数,给定一个字符串指示符,返回指定的字符串:

代码语言:javascript
运行
复制
(defun designated-string (string-designator)
  (ctypecase string-designator
    (string string-designator)
    (symbol (symbol-name string-designator))))

您还可以在宏和编译器宏中进行各种恶作剧,方法是检查给定形式的符号的名称,并应用一些约定(而不是…)。。

票数 3
EN

Stack Overflow用户

发布于 2019-10-13 17:53:11

当你处理符号名的时候就没那么傻了。例如,在构建预处理器时--读取一些数据,将其转换为列表结构,然后一些代码正在处理这些列表,并在symbol-namedefun-my-ubermacro时触发一些附加逻辑。这正是格雷厄姆引用的--你把符号当作数据。

而且(在我看来)这样说是不正确的,当你不使用褶皱时,你通常不使用符号作为数据。Plist只出现在许多有用功能的地方。宏所做的很多事情都是将符号作为数据/名称处理。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58365977

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档