首页 > 解决方案 > 在 lisp 编程中返回一个值

问题描述

我有一个功能

(defun read-as-list (filename)

    (defparameter parlist(list nil) )
    (let ((in (open filename :if-does-not-exist nil)))
        (when in
            (loop for line = (read-line in nil)
                 while line do
                    (defparameter mylist line)
                    (push mylist (cdr (last parlist)))
                    ;(append parlist (list mylist))
                    ;(print mylist)
                    ;(format t "~a~%" line)
            )
            (close in)
        )
    )
    (print parlist)
    (return-from read-as-list parlist)
)

它只需要一个文件名并将其读入嵌套列表并返回列表

我在 down 函数中调用它,例如:

(defun test_on_test_data ()
    (print "....................................................")
    (print "Testing ....")
    (print "....................................................")

    (let (con (read-as-list "document1.txt"))
        (print con)
    )   
)

(test_on_test_data)

在函数test-on-test-data中,con打印nil并且它不调用函数read-as-list

而不是打印文件的内容作为它打印的列表nil

有人可以帮我解决这个问题。

标签: lispcommon-lispreturn-valueletclisp

解决方案


这是一个示例函数,您可以使用它来测试如何迭代文件中的行。它接受一个路径名指示符和一个回调函数,并为文件中的所有行执行该函数。该函数必须接受一个参数,即正在读取的行。

(defun maplines (function path)
  (with-open-file (in path)
    (loop for line = (read-line in nil nil)
          while line
          do (funcall function line))))

请注意代码是如何缩进的,以及如何使用with-open-file. 此外,defparameter函数体内没有,因为该形式用于声明全局变量。不需要使用 return,因为函数体中的最后一个值自动是函数调用的值。

然后,您可以例如按如下方式调用它:

(maplines #'print "/tmp/test.data")

与您的代码不同,如果文件不存在,则会发出错误信号。在您的情况下,您通过nil在空流上给予和不做任何事情来默默地忽略错误。

最后,您只需要使用一个函数来存储正在读取的行。或者,如果您还不知道如何执行此操作,请修改上面的代码段以删除对 funcall 的调用并collect在循环中使用。您将获得所有行的列表。


推荐阅读