创建一个函数库来改变任意全局变量

 她能让你微笑衙 发布于 2023-02-13 10:55

更新:如果我有一些函数需要改变作为函数参数传递的全局变量,有些函数可以通过传递全局符号来实现(就像将某些东西推到列表的一部分一样) ,但是其他函数将要求在传递符号时引用符号,这样我就可以访问符号值并改变外部变量,这是在函数中使用setq所必需的.这个问题基本上是为这些函数的用户创建一致的界面,而不会混淆它们,有时你传递符号,othertimes你传递引用的符号

通过使用具有相同用法的帮助程序来简化一堆函数的接口的示例方法,无论变异函数如何工作:

以下是我的技术的两个基本示例:

(defun push-something (global something)
  (push something global)
  global) ;; not necessary to return it here since the 
          ;; preceding line already does, but doing so 
          ;; for consistency with other functions and clarity

(defun push-cdr (global something)
  (push something (cdr global))
  global) ;; must return it if I am going to set the 
          ;; dynamic var to the result of this function, 
          ;; because the preceding line doesn't return the 
          ;; entire new result of the variable

;;; "dirty" function for mutating global variable using "clean" functions above:

(defun set-global (fn global &rest values)
  (setf (symbol-value global) (apply fn (copy-list (eval global)) values)))

在这最后一个,我要evalglobal,因为它是引用与使用symbol-value,然后我copy-listglobal不直接不慎被任何突变fn我选择(因为会出现这种情况有push-cdr可能是在更复杂的功能不平凡的).

输出:

CL-USER> (defparameter *g2* nil)
*G2*
CL-USER> (set-global #'push-something '*g2* 5)
(5)
CL-USER> *g2*
(5)
CL-USER> (set-global #'push-cdr '*g2* 99)
(5 99)
CL-USER> *g2*
(5 99)

...和相同的功能可以与使用*g1**g3*等全部通过接入功能set-global.

这是好的还是坏的风格,还是我错过了更好的方法来实现这个功能?

1 个回答
  • 这是一种糟糕的风格,浪费你的时间.

      push-something相当于cons.

      push-cdr实用的:它修改就地参数或失败,对一个错误nil的参数.

    如果要更改全局变量的值,则setf显式使用更清晰.

    如果要以某种复杂的方式修改全局值的内部,可能需要为此编写一个特殊函数 - 但该函数应该不知道它正在修改绑定到全局变量的值而不是一个词汇变量.

    简而言之,有两个独立的正交问题 - 改变一个全局变量(使用setq)和改变一个对象的内部(不可知它的全局性).

    PS.我不确定你的意思是"setf在函数内部时不会改变全局变量的值",但是:

    (defvar *foo* 10)
    *FOO* ==> 10
    (defun change-foo (x) (setq *foo* x))
    (change-foo 123)
    *foo* ==> 123
    

    2023-02-13 10:56 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有