重新定义Racket中的变量列表

rns*_*nso 1 scheme racket

我可以一起定义许多变量,如下所示:

(match-define (list a b c) (list 1 2 3))
a
b
c
Run Code Online (Sandbox Code Playgroud)

输出:

1
2
3
> 
Run Code Online (Sandbox Code Playgroud)

但是,如何稍后在程序中重新定义这些变量?

本质上,我正在寻找“匹配重新定义”功能或宏。

以下操作无效:

(set! (list a b c) (list 10 20 30))
set!: not an identifier in: (list a b c)
Run Code Online (Sandbox Code Playgroud)

我也尝试过地图功能:

> (map set! (list a b c) (list 5 6 7))
. set!: bad syntax in: set!
> 
Run Code Online (Sandbox Code Playgroud)

我需要为此编写一个函数还是有一些简单的内置方法?

编辑:我尝试了以下match-redefine宏,该宏写在https://docs.racket-lang.org/guide/pattern-macros.html上swap宏的行上:

(match-define (list a b c) (list 1 2 3))

(println "------- sl --------")
(define sl (list a b c))
(println sl)

(println "------- vl --------")
(define vl (list 5 6 7))
(println vl)

(define-syntax-rule (match-redefine slist vlist)
  (for ((i slist) (j vlist))
    (set! i j)
  )
)

(println "----- expecting sl to become 5 6 7 ----------")
(match-redefine sl vl)
(println sl)
Run Code Online (Sandbox Code Playgroud)

但这行不通。输出为:

"------- sl --------"
'(1 2 3)
"------- vl --------"
'(5 6 7)
"----- expecting sl to become 5 6 7 ----------"
'(1 2 3)
Run Code Online (Sandbox Code Playgroud)

编辑:我发现火柴允许使用列表重新分配:

(define a 1)
(define b 2)
(define c 3)

(match-let ((  (list a b c) (list 100 200 300)  ))
  (println a)
  (println b)
  (println c)
)
Run Code Online (Sandbox Code Playgroud)

输出:

100
200
300
Run Code Online (Sandbox Code Playgroud)

但这不是“定义”或“设定!” 用于所有剩余的源文件。

soe*_*ard 5

问题是“在Racket中重新定义变量列表”。答案是你做不到!

您可以具有值列表,但不能具有变量列表。该表达式的(list a b c)计算结果为三个元素的列表:

> (define a 1)
> (define b 2)
> (define c 3)
> (list a b c)
(list 1 2 3)
Run Code Online (Sandbox Code Playgroud)

在球拍中,您可以给值命名:

> (define xs (list 1 2 3))
> xs
(list 1 2 3)
Run Code Online (Sandbox Code Playgroud)

现在,该变量xs引用一个值(三个数字的列表)。

您可以使用以下命令更改变量的含义set!:

> (set! xs (list 5 6 7))
(list 5 6 7)
Run Code Online (Sandbox Code Playgroud)

如果要同时更改三个变量,可以使用set-values!。

> (set!-values (a b c) (values 8 9 10))
> a
8
Run Code Online (Sandbox Code Playgroud)

该名称a,b并且c是标识符-发生在你的程序名。这意味着您不能将它们放在列表中。

由于符号的原因,我们可能会感到困惑:

 > '(a b c)
 '(a b c)
Run Code Online (Sandbox Code Playgroud)

这里的名称a,b,c不是变量或标识符。它们是符号。

字符串列表如下所示:

> '("a" "b" "c")
'("a" "b" "c")
Run Code Online (Sandbox Code Playgroud)

另一方面,打印的符号周围没有任何字符。

如果您有符号a并想要设置名称为a您的变量,则可以使用eval-但使用它eval是一个好主意非常罕见。我将留给您谷歌搜索“评估是邪恶的球拍”。

编辑:添加了一个不缺少的。