为什么终端停止响应 Enter 命令和我写的内容?
Why Terminal stop responding to Enter command and what I write?
我有一个列表 "straight":
(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)
。我正在尝试搜索 "straight" 并找到对应于 "Pitesti" 的值。但是,当我 运行 我的功能时,终端停止响应输入命令并且不响应我写的任何内容。这是函数:
(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)))))
首先,您的直接问题:eq
表示对象身份。我猜你给这个函数一个城市名称的单例列表,所以当你比较 (eq (car node) (caar s))
时,你比较两个字符串。只要这两个字符串不是同一个对象(如果它们都是从同一编译中作为文字读取的,则可能会发生这种情况——这在这里似乎不太可能),这就是错误的。相反,您应该使用 string=
.
由于您的比较从未 return 为真,该循环将继续设置 s
到 straight
的尾部,但请注意 cdr
的 [=20] =] 又是 nil
:这将永远不会终止。
因此,将 eq
替换为 string=
可能会解决您眼前的问题。但是,还有更多问题。
如果您传递的字符串实际上不存在于 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)
由于将列表的列表用于简单的关联结构相当普遍(“关联列表”或“列表”),因此有一种专门的形式:
(assoc (car node) straight
:test #'string=)
最后,一个明显的普遍问题:您一直在 setq
使用自由(很可能是未绑定的)变量。不要那样做。努力编写引用透明的函数。用 let
等建立局部绑定。当你有一个结果时,简单地 return 它,不要给它设置一些全局变量。
我有一个列表 "straight":
(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)
。我正在尝试搜索 "straight" 并找到对应于 "Pitesti" 的值。但是,当我 运行 我的功能时,终端停止响应输入命令并且不响应我写的任何内容。这是函数:
(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)))))
首先,您的直接问题:eq
表示对象身份。我猜你给这个函数一个城市名称的单例列表,所以当你比较 (eq (car node) (caar s))
时,你比较两个字符串。只要这两个字符串不是同一个对象(如果它们都是从同一编译中作为文字读取的,则可能会发生这种情况——这在这里似乎不太可能),这就是错误的。相反,您应该使用 string=
.
由于您的比较从未 return 为真,该循环将继续设置 s
到 straight
的尾部,但请注意 cdr
的 [=20] =] 又是 nil
:这将永远不会终止。
因此,将 eq
替换为 string=
可能会解决您眼前的问题。但是,还有更多问题。
如果您传递的字符串实际上不存在于 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)
由于将列表的列表用于简单的关联结构相当普遍(“关联列表”或“列表”),因此有一种专门的形式:
(assoc (car node) straight
:test #'string=)
最后,一个明显的普遍问题:您一直在 setq
使用自由(很可能是未绑定的)变量。不要那样做。努力编写引用透明的函数。用 let
等建立局部绑定。当你有一个结果时,简单地 return 它,不要给它设置一些全局变量。