【问题标题】:Shadowing parts of a dynamic variable阴影部分动态变量
【发布时间】:2017-08-23 15:56:36
【问题描述】:

也许我在这里太有创意了。

是否可以将动态绑定的概念扩展到动态变量的SETFable places,以便我可以隐藏动态变量的部分(例如作为 plist) 与 LET 绑定?

例如,我希望能够执行以下操作:

(defparameter *foo* '(:one 1))

(let (((getf *foo* :one) 2))
  (do-things))

用 2 遮蔽 :one 的值。

此示例不起作用,因为(getf *foo* :one) 不是LET 可以为其赋值的变量名,但也许还有其他方法?

【问题讨论】:

  • 在 plists 和 alists 的情况下,您可以隐藏以前的绑定而不是修改底层列表(这可能对并发/可重入代码有问题):(let ((*foo* (list* :one 2 *foo*))) ...)

标签: common-lisp dynamic-binding


【解决方案1】:

没有标准方法,但某些实现可能会提供 扩展名,例如,letf

或者,您可以使用 unwind-protect你自己:

(let ((old-value (getf *foo* :one)))
  (unwind-protect
       (progn (setf (getf *foo* :one) 2)
              (do-things))
    (setf (getf *foo* :one) old-value)))

如果这是您代码中的常见操作,您甚至可以为此定义一个宏:

(defmacro with-one (tmp-one &body body)
  "Bind (getf *foo* :one) to tmp-one around body."
  (let ((old-value (gensym "WITH-ONE-OLD")))
    `(let ((,old-value (getf *foo* :one)))
       (unwind-protect
            (progn (setf (getf *foo* :one) ,tmp-one)
                   ,@body)
         (setf (getf *foo* :one) ,old-value)))))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-15
    • 1970-01-01
    • 2014-10-23
    相关资源
    最近更新 更多