아래 코드에서와 같이 하나의 인수를 허용하는 클로저를 만드는 함수를 정의합니다.이 값은이 클로저의 컨텍스트에서 바인드 된 변수를 나타내는 기호입니다. 클로저의 본문에서는 symbol-value
을 사용하여 심볼 값을 가져 오지만 Symbol's value as variable is void
이라는 오류 메시지가 표시되면이 스 니펫이 123
으로 표시 될 것으로 예상됩니다.Elisp에서 클로저에서 로컬로 바인딩 된 심볼의 값 셀에 액세스하는 방법은 무엇입니까?
symbol-value
이 작동하지 않는 이유 :그래서 나는 여기 두 가지 질문이 있습니까?
- 원하는 스 니펫을 수정하여 원하는 결과를 얻으려면 어떻게해야합니까? 업데이트
(defun make-closure() (lexical-let ((var1 123)) (lambda (name) ;; How can I get the value cell of the symbol ;; specified by the argument "name" ? ;; This doesn't work. (message-box (format "%s" (symbol-value name)))))) (let ((closure (make-closure))) (funcall closure 'var1))
사실,이 질문이 있어요. 처음에는 ( 스테판의 대답의 두 번째 코드와 유사하다)이 같은했다 :
(defun new-person (initial-name)
(lexical-let* ((name initial-name)
(say-hi (lambda()
(message-box (format "Hi, I'm %s" name))))
(change-name (lambda (new-name)
(setq name new-name))))
(lambda (selector &rest args)
(cond
((equal 'say-hi selector) (apply say-hi args))
((equal 'change-name selector) (apply change-name args))
(t (message-box "Message not understood"))))))
(let ((tony (new-person "Tony")))
(funcall tony 'say-hi)
(funcall tony 'change-name "John")
(funcall tony 'say-hi))
을하지만 "COND"좀 "상용구"의 조항을 느꼈다 나는 이 가능한 수 있습니다 그것을 생각 인수에서 전달 된 기호를 사용, 그래서 더 이상 작동 다음, 그것을 수정,하지만 난 왜 알아낼 수 없습니다 :
이(defun new-person (initial-name)
(lexical-let* ((name initial-name)
(say-hi (lambda()
(message-box (format "Hi, I'm %s" name))))
(change-name (lambda (new-name)
(setq name new-name))))
(lambda (selector &rest args)
(apply (symbol-value selector) args))))
그래서 우리가 사용하지 않도록 말을하는 것입니다 어휘 적으로 바운드 변수 인 을 참조하는 기호 위와 같이 닫는다. 평가에서 그들 중 이라는 이름은 그들 자신이 과 똑같은 것으로 보증 되었기 때문에 말이다.
어휘 변수는 단순히 클로저 외부에서 액세스 할 수있는 것은 아닙니다. 그것은 다소 중요합니다. 이러한 변수에 액세스해야하는 경우 어휘 바인딩은 처음에는 잘못된 선택이었으며 그 방법을 찾기 위해 시도하는 것이 좋은 생각이라고 생각하지 않습니다. – phils