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如何在内部工作的更多细节,这可能对初学者更有用。