球拍:获取名称存储在另一个变量中的变量的值

Racket: Get the value of a variable who's name is stored in another variable

我有一个变量 "name",它的值是另一个变量的名称。 例如:

(define name 'a)
(define a 1)

然后我想做这样的事情:

(set! ,name 10)

但这会导致错误,因此我希望将“,name”替换为它的值(即“a”)。所以上面的代码将变量 "a" 的值设置为 10 而 "name" 变量保持不变。

我知道我可以这样做:

(eval `(set! ,name 10))

但这只有当"name"中包含的变量是一个全局变量时才有效,而在我的程序中不是这样。

目前我通过引入一个新的命名空间解决了这个问题,但这使得代码有点难看,这就是为什么我会避免使用 eval(因此也避免引入一个新的命名空间)。

如果我没有在 C++ 中误会我的话,这将通过取消引用句柄(指向指针的指针)来完成。

(eval `(set! ,name 10)) 不起作用的原因是局部变量的名称在运行时不存在。局部变量存储在堆栈中,因此对局部变量的引用和赋值被编译为 "get the value in the i'th variable (counted from the top of the stack)" 和 "store this value in the i'th slot at the stack".

然而,模块级变量存储在命名空间中,因此您可以对它们使用 eval 解决方案。

那么局部变量怎么办呢?最好使用散列 table 代替,但如果您 真的 需要它,请执行以下操作:

(define (set-local-variable name val)
  (match name
    ['a (set! a val)]
    ['b (set! b val)]
    ...))

其中 a、b、... 是局部变量。您当然需要将定义放在相关局部变量的范围内。这也意味着您需要为每个范围定义一个 set-local-variable

维护起来很快就会很痛苦,因此寻找替代解决方案 - 例如基于散列 tables 的解决方案。