Garbage collection 为什么每个映射都保留最后一个值作为对要设置的单词的引用?

Garbage collection 为什么每个映射都保留最后一个值作为对要设置的单词的引用?,garbage-collection,block,rebol,rebol3,rebol2,Garbage Collection,Block,Rebol,Rebol3,Rebol2,map each可用于为集合中的每个成员计算某些代码,并将计算结果聚合到块中: >> values: map-each x [1 2] [ print ["Doing mapping for" x] x * 10 ] Doing mapping for 1 Doing mapping for 2 == [10 20] 我用这种方法建造了一个街区。但是我忘记了,由于默认情况下不会计算块,因此x将保持原样,不会得到我想要的值: >> blocks: m

map each
可用于为集合中的每个成员计算某些代码,并将计算结果聚合到块中:

>> values: map-each x [1 2] [
    print ["Doing mapping for" x]
    x * 10
   ]
Doing mapping for 1
Doing mapping for 2
== [10 20]
我用这种方法建造了一个街区。但是我忘记了,由于默认情况下不会计算块,因此
x
将保持原样,不会得到我想要的值:

>> blocks: map-each x [1 2] [
    print ["Doing mapping for" x]
    [x * 10]
   ]
Doing mapping for 1
Doing mapping for 2
== [[x * 10] [x * 10]]
这并不奇怪。经过评估后,
x
没有任何价值——更不用说接受许多价值的能力:

>> probe x
** Script error: x has no value
因此,现在已经太迟了,必须在地图主体内部使用REDUCE或COMPOSE来完成评估。但是

>> reduce first blocks
== [20]

>> reduce second blocks
== [20]
结果块中项目的计算不会抛出错误,但其行为就像
x
具有上一次迭代的值一样

它是怎么做到的?它应该这样做吗

blocks: map-each x [1 2] [
    print ["Doing mapping for" x]
    [x * 10]
]

probe bound? first blocks/1
给这个

Doing mapping for 1
Doing mapping for 2
make object! [
    x: 2
]

就像“FOREACH”一样,MAP-EACH将您提供给它的块绑定到它创建的上下文中并在那里执行

X永远不会全局创建。您将一个单词(而不是lit单词)作为参数的事实由函数的接口管理,该接口可能使用lit单词表示法,并使用给定的单词(即未计算的单词),而不是它可能包含的值

因此,调用map each时使用的X不会触发

** Script error: x has no value
因为map-each在计算它之前就抓取它,并且只直接使用这个词作为标记

来说明绑定如何更有效地工作,并展示X如何在其原有的上下文中生存下去,这里有一个例子说明了如何在ReBOL中绑定单词(以及这个绑定仍然存在的事实)。p> 看看这个例子:

a: context [x: "this"]  
b: context [x: "is"]  
c: context [x: "sensational!"]

>> blk: reduce [in a 'x   in b 'x   in c 'x]
== [x x x]

x: "doh!"
== "doh!"

>> probe reduce blk
["this" "is" "sensational!"]
我们创建了一个包含三个“X”字的块,但它们都没有绑定到同一上下文

因为Rebol中的绑定是静态的,并且作用域不存在,所以同一个单词可以有不同的值,即使它们在相同的上下文中被操作(在这种情况下,控制台是全局|用户上下文)


这是为什么单词在Rebol中不是变量的倒数第二个示例。

听起来该块仍然绑定到map each生成的匿名上下文,因此x保留其最后一个值。注意:我的答案比原来的问题大一点,但它提供了Rebol如何在内部工作的更多细节,这可能对初学者更有用。