2017-09-24 7 views
0

나는 "똑바로"목록의 목록이 있습니다왜 터미널이 Enter 명령에 응답하지 않고 무엇을 씁니까?

(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

무한 루프처럼 보이므로 중지해야 할 수도 있습니다 ... –

답변

2

먼저, 즉각적인 문제 : eq 수단의 정체성을 객체. 이 함수에 도시 이름의 싱글 톤 목록을 주면, (eq (car node) (caar s))을 비교할 때 두 개의 문자열을 비교할 것입니다. 이 두 문자열이 같은 객체가 아니라면 (이것은 동일한 컴파일에서 리터럴로 읽을 때 일어날 수 있습니다. —) 여기서는 틀릴 것입니다. 대신 string=을 사용해야합니다.

당신의 비교는 결코 true를 반환하지 않기 때문에, 그 루프 straight의 꼬리에 s 설정을 계속하지만, nilcdr 다시 nil를 대상이므로주의한다 :이 종료하지 않습니다.

따라서 eqstring=으로 바꾸면 즉각적인 문제를 해결할 수 있습니다. 그러나 더 많은 문제가 있습니다.

전달한 문자열이 실제로 straight에 없으면 어떻게됩니까? 그런 다음 다시는 종결되지 않습니다. 더 좋은 방법이 루프를 수행하는 :

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

for-in 구조가 목록의 마지막에 종료됩니다, 그래서 문자열이 누락 된 경우 다시 nil을 얻을 것이다. thereis : Loop 뭔가 찾을 수있는 또 다른 구조가 발견의

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

말하기를, 왜 loop 대신 find를 사용하지 :

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

을 간단한 연관 구조 목록의 목록을 사용하기 때문에 오히려 일반적이다 ("협회 목록"또는 "알리 스트")에는 다음과 같은 특수 형식이 있습니다.

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

마지막으로 눈에 띄는 일반적인 문제는 다음과 같습니다. setq 무료 (대부분 언 바운드) 변수가 있습니다. 그러지 마. 참조가 가능한 투명 기능을 작성하려고 노력하십시오. let 등으로 국지 바인딩을 설정하십시오. 결과가 나오면 간단히 리턴하십시오. 일부 전역 변수를 설정하지 마십시오.