为什么终端停止响应输入命令,我写了什么?

问题描述:

我的名单“直”的列表:为什么终端停止响应输入命令,我写了什么?

(setq straight '(
     ("Arad"    366) 
     ("Bucharest"   0) 
     ("Craiova"   160) 
     ("Dobreta"   242) 
     ("Eforie"   161) 
     ("Fagaras"   176) 
     ("Giurgiu"   77) 
     ("Hirsova"   151)  
     ("Iasi"    226) 
     ("Lugoj"   244) 
     ("Mehadia"   241) 
     ("Neamt"   234) 
     ("Oradea"   380) 
     ("Pitesti"   100) 
     ("Rimnicu Vilcea" 193) 
     ("Sibiu"   253) 
     ("Timisoara"  329) 
     ("Urziceni"   80) 
     ("Vaslui"   199) 
     ("Zerind"   374))) 

而且我有一个列表("Pitesti" 101)。我试图通过“直接”搜索并找到与“皮特什蒂”相对应的价值。但是,当我运行我的功能,终端停止响应输入命令,并没有回应我写的任何东西。这里的功能:

(defun her (node) 
    (setq s straight) 
    (setq c '()) 
    (loop while (not (eq (car node) 
         (caar s))) 
     do (setq s (cdr s))) 
    (setq c (append node (car (cdar s))))) 
+1

由于它看起来像一个无限循环,你可能想要停止它... –

首先,你的直接问题:eq意味着对象的身份。我想你会给这个函数提供城市名称的单例列表,所以当你比较(eq (car node) (caar s))时,你会比较两个字符串。只要这两个字符串不是同一个对象(如果这两个字符串都是从同一个编译—这两个字符中读取的,这在这里看起来不太可能),这将是错误的。相反,您应该使用string=

因为你比较不会返回true,则循环将继续设置sstraight尾巴,但要注意的nilcdr再次nil:这不会终止。

因此,用string=替换eq可能会解决您的紧急问题。但是,还有更多问题。

如果您传递的字符串实际上并不存在于straight中,会发生什么情况?然后再次,它永远不会终止。一个更好的办法来做到这一点循环:

(loop :for pair :in straight 
     :when (string= (car node) (car pair)) 
     :do (return pair)) 

for - in结构将在列表的最后终止,所以你会得到nil如果字符串丢失。 Loop有另一种构建找到的东西:thereis

(loop :for pair :in straight 
     :thereis (when (string= (car node) (car pair)) pair)) 

发现的说起,为什么不使用find代替loop

(find (car node) straight 
     :test #'string= 
     :key #'first) 

由于使用列表的列表简单的关联结构是相当普遍(“关联名单”或“alist”),这里有专门的表格:

(assoc (car node) straight 
     :test #'string=) 

最后,一个令人瞩目的普遍问题是:你自始至终都是免费的(最有可能是未绑定的)变量。不要这样做。努力写出引用透明的功能。建立与let等本地绑定。当你有一个结果,只需返回它,不要设置一些全局变量。