为了全能的爱,我还没有理解符号'iamasymbol
的目的。我理解数字,布尔值,字符串...变量。但是符号对于我的小思维思维来说太过分了。我究竟用它做什么用的?它们应该如何在程序中使用?我对这个概念的掌握是失败的。
答案 0 :(得分:29)
符号是一个具有简单字符串表示形式的对象(默认情况下)保证实习;也就是说,任何两个写成相同的符号都是内存中的同一个对象(引用相等)。
为什么Lisps有符号?好吧,它主要是Lisps将自己的语法作为语言的数据类型嵌入的事实。编译器和解释器使用符号来表示程序中的标识符;由于Lisp允许您将程序的语法表示为数据,因此它提供符号,因为它们是表示的一部分。
除此之外它们有什么用处?嗯,有几点:
答案 1 :(得分:28)
在Scheme和Racket中,符号就像一个不可变的字符串恰好被实现,因此符号可以与eq?
进行比较(快速,基本上是指针比较)。符号和字符串是单独的数据类型。
符号的一个用途是轻量级枚举。例如,可以说方向是'north
,'south
,'east
或'west
。你当然可以使用字符串来达到同样的目的,但效率会稍差。使用数字是个坏主意;尽可能以明显和透明的方式表示信息。
另一个例子,SXML是使用列表,符号和字符串表示XML。特别是,字符串表示字符数据,符号表示元素名称。因此,XML <em>hello world</em>
将由值(list 'em "hello world")
表示,可以更紧凑地编写'(em "hello world")
。
符号的另一个用途是作为键。例如,您可以将方法表实现为将符号映射到实现函数的字典。要调用方法,请查找与方法名称对应的符号。 Lisp / Scheme / Racket使真正变得容易,因为语言已经在标识符(语言的语法的一部分)和符号(语言中的值)之间具有内置的对应关系。这种对应使得支持宏变得容易,它实现了用户定义的语言语法扩展。例如,可以使用“方法名称”(由类系统定义的语法概念)与符号之间的隐式对应关系,将类系统实现为宏库:
(send obj meth arg1 arg2)
=>
(apply (lookup-method obj 'meth) obj (list arg1 arg2))
(在其他Lisps中,我所说的大部分都是真实的,但还有其他一些事情需要了解,比如包和功能与可变插槽,IIRC。)
答案 2 :(得分:7)
lisp中的符号是人类可读的标识符。他们都是单身人士。因此,如果您在代码中的某处声明'foo然后再次使用'foo,它将指向内存中的相同位置。
样本使用:不同的符号可以代表棋盘上的不同部分。
答案 3 :(得分:5)
符号只是值的特殊名称。值可以是任何值,但该符号用于每次引用相同的值,并且此类事物用于快速比较。正如你所说的那样,你在思考它们,它们就像C中的数字常量,这就是它们通常被实现的方式(内部存储的数字)。
答案 4 :(得分:3)
来自计算机程序的结构和解释第二版,作者:Harold Abelson和Gerald Jay Sussman 1996:
为了操纵符号,我们需要在我们的语言中使用新元素: 引用数据对象的能力。假设我们要构建列表 (a b)。我们无法用(列出一个b)完成这个,因为这个表达式 构造a和b的值的列表而不是符号本身。 这个问题在自然语言的背景下是众所周知的 和句子可以被视为语义实体或字符 字符串(句法实体)。自然语言中的常见做法是使用引号来表示要处理单词或句子 字面意思是一串字符。例如,“约翰”的第一个字母是 显然是“J。”如果我们告诉某人“大声说出你的名字”,我们希望听到 那个人的名字。但是,如果我们告诉某人“大声说出你的名字”, 我们希望听到“你的名字”这个词。注意我们被迫窝 用引号来描述别人可能会说的话。 我们可以按照相同的做法来识别列表和符号 被视为数据对象而不是要评估的表达式。 但是,我们的引用格式与自然语言的格式不同 我们放置一个引号(传统上,单引号') 仅在要引用的对象的开头。我们可以在Scheme语法中使用它,因为我们依赖空格和括号来分隔 对象。因此,单引号字符的含义是引用 下一个对象。 现在我们可以区分符号及其值:
{{1}}
包含符号的列表看起来就像我们语言的表达式:
{{1}}
示例:符号分化