1

我编写了一个函数来查询我为学校编写的小型数据库程序。此函数按名称搜索。当我自己运行该功能时,它可以工作。当我在菜单中运行它时它不起作用(它返回 NIL)。这是所有相关的内容:

(defun prompt-read (prompt)                                                    
  (format *query-io* "~a: " prompt)                                            
  (force-output *query-io*)                                                    
  (read-line *query-io*)) 

(defun search-name (name)                                                      
  (remove-if-not                                                               
   #'(lambda (cat) (equal (getf cat :name) name)) *db*))                       

(defun input-name ()                                                           
  (search-name                                                                 
   (prompt-read "Name")))

(defun search-menu ()                                                          
  (print "1) Search Name")                                                     
  (print "2) Search Color")                                                    
  (print "3) Search Min. Weight")                                              
  (print "4) Search Min. Experience")                                          
  (print "5) Search Min. Length")                                              
  (setf choose (read))                                                         
  (cond ((= choose 1)(input-name))                                             
        ((= choose 2)(print "Color"))                                          
        ((= choose 3)(print "Weight"))                                         
        ((= choose 4)(print "XP"))                                             
        ((= choose 5)(print "Color"))                                          
  )                                                                            
  NIL                                                                          
)  

现在我只致力于让名称搜索工作,菜单的其余部分只是占位符。当我自己运行“输入名称”(使用搜索名称)时,它会返回正确的结果。当我尝试搜索菜单中的第一个选项(也运行“输入名称”)时,它返回 NIL。我想知道为什么当我单独运行它时它会起作用,但与该菜单一起使用时却不起作用。如果有人需要任何其他信息,请随时询问。我会尽力提供。另外,我是初学者,请见谅。

4

3 回答 3

2

如果你想在程序中输出,那么你需要打印一些东西。

(defun example ()
  1000)

上述函数不打印任何内容。它只是返回一个数字。

如果我们在 read-eval-print-loop 中调用它:

CL-USER 134 > (defun example ()
                1000)
EXAMPLE

CL-USER 135 > (example)
1000

您会看到 1000 被打印出来。但为什么?

我们在 READ- EVAL- PRINT - LOOP 中运行它。读取、评估、打印、循环。

意味着:Lisp 系统正在打印评估的返回值,而不是您的代码。

现在我们添加一个打印调用:

CL-USER 136 > (defun example ()
                (print 1000))
EXAMPLE

CL-USER 137 > (example)

1000 
1000

打印了两次!

CL-USER 137 > (example)

1000     ; <- the function example prints 
1000     ; <- the read-eval-print-loop prints the result

所以我们的函数现在自己打印一些东西,因为它调用了PRINT.

现在这有效:

CL-USER 138 > (defun call-the-example ()
                (example)
                (values))
CALL-THE-EXAMPLE

CL-USER 139 > (call-the-example)

1000 

我们可以调用example函数,函数打印一些东西,而 REPL 什么也不打印。

REPL 什么也不打印,因为call-the-example什么也不返回。它不返回任何值。

因此,您需要添加 PRINT 调用

添加打印调用是正确的,但原因很简单,就是在您没有打印之前没有打印调用(input-name)。您正在调用(input-name)READ-EVAL-PRINT-LOOP,然后打印结果。不是您的代码,而是 REPL 确实输出了。

样式:未定义变量

(defun foo ()
  (setf bar 10)  ; <- BAR is undefined
  (print bar)    ; <- BAR is undefined
  (setf bar 20)  ; <- BAR is undefined
  (print bar))   ; <- BAR is undefined

改写这个 -LET用来定义一个局部变量:

(defun foo ()
  (let ((bar 10))    ; define BAR
    (print bar)      ; BAR is defined
    (setf bar 20)    ; BAR is defined
    (print bar)))    ; BAR is defined
于 2020-02-05T20:14:26.193 回答
0

search-menu对 from 的返回值不做任何事情input-name。函数返回它执行的最后一个表达式的值,而最后一个表达式search-menuis NIL,所以这就是它返回的内容。

如果您希望它返回cond表达式的值,请NIL从末尾删除。

您还应该使用let声明一个局部变量,而不是分配未定义的变量choose

(defun search-menu ()
  (print "1) Search Name")
  (print "2) Search Color")
  (print "3) Search Min. Weight")
  (print "4) Search Min. Experience")
  (print "5) Search Min. Length")
  (let ((choose (read)))
    (cond ((= choose 1) (input-name))
          ((= choose 2) (print "Color"))
          ((= choose 3) (print "Weight"))
          ((= choose 4) (print "XP"))
          ((= choose 5) (print "Color")))))
于 2020-02-12T14:59:55.853 回答
-1

我最终找到了一个解决方案,只需在 input-name 函数中使用 print 即可。这个函数只需要显示结果,所以它工作得很好。

(defun input-name ()                                                           
  (print                                                                       
  (search-name                                                                 
   (prompt-read "Name")))) 

与以前相同的功能,但增加了打印。现在它也可以在菜单中使用。

于 2020-02-05T16:33:34.073 回答