你们都知道这个故事:程序员读取其他人的代码,程序员看到他们不理解的符号,谷歌失败了,因为搜索非字母数字符号很困难.
这次它是@符号,似乎用于将一个列表的内容注入另一个列表的中间.例如:
`(5 6 7 ,@'(8 9) 10 11)
;=> (5 6 7 8 9 10 11)
Run Code Online (Sandbox Code Playgroud)
我很满意这种用法,但我想知道我是否理解@正确的行为?它有其他用途吗?以下成绩单中的错误是什么原因(来自CLISP)?
[1]> (list 1 2 3 4 @'(5 6 7))
*** - SYSTEM::READ-EVAL-PRINT: variable @ has no value
Run Code Online (Sandbox Code Playgroud)
最后,到底是 @什么?它似乎不是一个功能:
[3]> (print #'@)
*** - FUNCTION: undefined function @
Run Code Online (Sandbox Code Playgroud)
我猜这是一个基本的语法,如backquote(`)或逗号(,).它是否正确?对不起,如果这是重复的,但是再一次,据我所知,它是不可能搜索的@.
Jos*_*lor 14
它在HyperSpec的backquote部分中描述:
2.4.6反引号
如果逗号后面紧跟着符号,则会评估符号后面的表单以生成对象列表.然后将这些对象"拼接"到模板中的适当位置.例如,如果
x有值(a b c),那么Run Code Online (Sandbox Code Playgroud)`(x ,x ,@x foo ,(cadr x) bar ,(cdr x) baz ,@(cdr x)) => (x (a b c) a b c foo b bar (b c) baz b c)
值得注意的是,这,@并非总是必要的; 根据相同的文件:
可以使用Anywhere",@",而不是使用语法",."来表示允许在","之后的表单生成的列表结构上进行破坏性操作(实际上,使用nconc代替附加).
当你问道时,你的直觉大多是正确的,"所以基本上@本身就没有任何意义,唯一真正的运算符是,@?" @可以在其他地方用作普通字母.这就是为什么你得到你提到的错误:(list 1 2 3 4 @'(5 6 7))简单
(list 1 2 3 4 @ '(5 6 7))
Run Code Online (Sandbox Code Playgroud)
并且@是一个变量,但它在这里没有值.与之相比:
(let ((@ 4.5))
(list 1 2 3 4 @ '(5 6 7)))
;=> (1 2 3 4 4.5 (5 6 7))
Run Code Online (Sandbox Code Playgroud)
很抱歉,如果这是重复的,但据我所知,再一次,我不可能搜索"@".
搜索某些非字母数字字符的文档可能很困难,但我发现了一些可以提供帮助的技术.例如,如果你去lispdoc.com,你可以搜索comma,结果会让你走向反引号.(搜索at-sign虽然没有帮助.)这不是一个完美的解决方案,但它有时会有所帮助.
,@应被视为单个实体,其含义,@是将以下表达式拼接到当前的准引用列表中.
例如,你不能使用
`,@x
Run Code Online (Sandbox Code Playgroud)
因为准引用的表达式不是列表,,@需要拼接列表.同样(在我阅读标准时)你不能使用
`(list ,@5)
Run Code Online (Sandbox Code Playgroud)
因为5它不是一个列表(但是SBCL和CLISP都允许它并扩展到(list . 5)).
实际上,SBCL和CLISP的行为是可以接受的,但如果,@与非列表参数一起使用,则兼容的实现也可以接受错误.
CLHS第2.4.6节最后可能扩展的`((,a b) ,c ,@d)节目也可以接受为非列表提出错误.
| 归档时间: |
|
| 查看次数: |
1618 次 |
| 最近记录: |