我在这里检查了如何循环文件的帖子.我在网上检查了几个地方,试图了解在这里发布的代码中发生了什么:
(defun get-file (filename)
(with-open-file (stream filename)
(loop for line = (read-line stream nil)
while line
collect line)))
Run Code Online (Sandbox Code Playgroud)
这种语法似乎是如此神秘,而且引用并不容易理解.根据这里的引用"七个中的第四个/作为语法",语法是:
for var [type-spec] = expr1 [then expr2 ]
如果没有expr2,则使用expr1.
令我困惑的是什么:
除了如何工作之外我不知道该问什么,我迷失了方向:
while line
collect line
Run Code Online (Sandbox Code Playgroud)
我不知道如何用其他代码替换它.它看起来不像一个列表.我的直觉会告诉我它应该看起来像:
(while line (collect line))
Run Code Online (Sandbox Code Playgroud)
此外,不是同样如下:
while line collect line
Run Code Online (Sandbox Code Playgroud)
什么是expr1:
(read-line stream nil)
while line
collect line)
Run Code Online (Sandbox Code Playgroud)
要么
while line
collect line
Run Code Online (Sandbox Code Playgroud)
如果我有更多代码而不是collect line?会不会有名单?我没有看到结构.
我知道这些不仅仅是一个问题,但可能有一些我想念的大事,阻止我提出一个好问题.
这是一个循环.多次运行的东西.
基本上循环有两个部分:
line以及它发生了什么:在每个循环中迭代line被设置为评估表达式的结果(read-line stream nil).这意味着逐行读取行.line没有nil收集line到列表中的值.因此,每行都被读取,只要有一行,就将其收集到一个列表中.如果到达输入流的末尾(这是一个文件流),(read-line stream nil)表单返回nil,while看到的line是nil.nil是假的,因此循环终止.然后将返回到目前为止收集的行作为结果.
整个loop表单返回收集的行列表.
这loop很方便,因为:
collect ...子句.背景
通常LOOP是一个宏,它基于FOR70年代早期Interlisp 的类似宏.有一个想法被引入有程序结构可以像普通英语一样使用:对于列表收集项目中的项目.这被称为会话Lisp.类似的想法例如在Apple的简单脚本语言Applescript中使用.这种风格在Lisp中从未如此受欢迎(虽然还有其他宏使用它),但loop宏仍然存在,因为它证明是有用的.