通过闭包创建实例

问题描述 投票:0回答:1

我正在阅读示例3.1Assignment and Local State from SICP

#+begin_src scheme 
(define (make-withdraw balance)
  (lambda (amount)
    (if (>= balance amount)
        (begin (set! balance (- balance amount))
               balance)
        "Insufficient funds")))
(define W1 (make-withdraw 100))
(W1 50)
(W1 30)
#+end_src

#+RESULTS:
: 20

实践与elisp

#+begin_src emacs-lisp lexical t
(defun make-withdraw(balance)
  (lambda (amount)
    (if (>= balance amount)
        (progn (setq balance (- balance amount))
               balance)
        "Insufficient funds")))
(make-withdraw 10)
(defvar W1 (make-withdraw 100))
(funcall (W1 30))
#+end_src

#+RESULTS:
: W1

未按预期工作,请进行交互试验

情况1:直接调用make-withdraw并返回闭包

;; lexical-binding t 
ELISP> (make-withdraw 100)
(closure
 ((balance . 100)
  t)
 (amount)
 (if
     (>= balance amount)
     (progn
       (setq balance
             (- balance amount))
       balance)
   "Insufficient funds"))

案例2:将其分配给W1,但返回一个通用函数而不是闭包

ELISP> (defvar W1 (funcall (withdraw 100)))
W1
ELISP> W1
(lambda
  (amount)
  (if
      (>= balance amount)
      (progn
        (setq balance
              (- balance amount))
        balance)
    "Insufficient funds"))

如何创建实例W1

elisp sicp
1个回答
1
投票
ELISP> (defvar W1 (funcall (withdraw 100)))

[withdraw不是make-withdraw-您叫了别的东西。

ELISP> W1
(lambda ...)

并且在lexical-binding处于活动状态时还没有定义其他内容,否则您将看到一个闭包。

至此...

(make-withdraw 10)
(defvar W1 (make-withdraw 100))
(funcall (W1 30))

您正在将功能分配给变量 W1,这意味着(如您从此处的其他近期问题中所知道的),您不能使用(W1 30),而必须使用[C0 ]

© www.soinside.com 2019 - 2024. All rights reserved.