【问题标题】:Specifying which value to return in lisp指定要在 lisp 中返回的值
【发布时间】:2011-12-06 19:31:22
【问题描述】:

我对 lisp 编程完全陌生。我需要为一个从 xml 文档中读取单词的类编写一个程序。不管怎样,我写了这个函数,它接受一个数组(word)和一个文件流(in)。我希望它循环直到它到达流中的#\space,同时将每个收集的字符添加到单词中。然后我想要返回这个词。我确定我做错了很多事情,但这是我的方法。我相当肯定最后的返回函数完全不合适:

(defun get-string (in word)
  (loop for char = (read-char in nil)
      while (not (char= char #\space))
      do(vector-push-extend char word))
  (return word))

现在我有另一个问题。循环在找到空格后继续寻找字符,我得到了一堆 nil。另外,我需要在换行符上停下来,但不知道该怎么做。我绑定了这个,但它只读取每个字符。

(defun get-string (in word)
 (loop for char = (read-char in nil)
      while (not (or (char= char #\space)
                (char= char #\newline)))
    do(print char))
  word)

打印字符在那里,因为我不太擅长理解调试器并且想看看我正在阅读什么字符。

【问题讨论】:

    标签: parsing io lisp


    【解决方案1】:

    word 是一个变量,变量的计算结果是它的值。在DEFUN 正文中,返回最后一个表达式的值。所以word附近的return是不需要的,如果你想返回word的值。

    【讨论】:

      【解决方案2】:

      您不需要明确的return 语句。这仅适用于词法范围的早期返回。所以这个版本有效:

      (defun get-string (in word)
        (loop for char = (read-char in nil)
              while (not (char= char #\space))
              do (vector-push-extend char word))
        word)
      

      但我想知道你的函数中的另一件事:参数这个词是否意味着只传递空数组?你不需要传递缓冲区来处理字符串,Lisp 不是 C。感谢自动内存管理,你可以在函数中创建字符串并返回它们。

      因此,我会编写一个函数来从这样的流中读取空格分隔的单词:

      (defun read-word (&optional (stream *standard-input*))
        (with-output-to-string (word)
         (loop for char = (read-char stream nil)
               while (and char
                          (char/= char #\Space)
                          (char/= char #\Newline))
               do (write-char char word))))
      

      关于您新添加的问题:我不明白为什么当您阅读空格时您的循环不应该停止。 OTOH,您没有检查的是 NIL,即 EOF 情况下的返回值。这就是为什么我在我自己的函数中的and 中添加了第一个条件(只是char)。

      编辑:用一个不使用自己的行缓冲的函数替换我自己的函数,因为这很脆弱,太复杂,而且在这里没有必要。另外,添加了对扩展问题的答案。

      【讨论】:

      • 我不完全确定我理解你的意思,但我正在传递流,因为我正在从文件中读取单词。在此函数之前,我使用另一个函数跳过包含在 中的任何文本,然后将流传递给 get-word 函数,该函数将字符串拉入 xml 标记之间。
      • 你觉得关闭是个好主意吗?从不同的流中读取怎么样?线程安全? LET 还可以防止 DEFUN 成为通常应该是的顶级构造。
      • @RainerJoswig:我从一个运行良好的程序中复制了代码。但是你可能是对的,它会导致问题的情况太多,因此我将在编辑中替换它。
      • @webhound:我不是指流参数。我提出的函数也接受一个流参数。我的意思是论点word。您是否真的想将新字符附加到该数组的先前内容中,还是只是传入一个(假定为 emtpy)缓冲区?
      • @RainerJoswig:实际上在传入单词时已经附加了一个字符。这是一个丑陋的程序。我仍在努力习惯口齿不清。我只使用它大约一个星期。无论如何,我正在废弃原始程序并尝试不同的方法。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-27
      • 2020-02-15
      • 1970-01-01
      • 1970-01-01
      • 2021-04-17
      • 1970-01-01
      相关资源
      最近更新 更多