Logo是我小时候学过的第一种编程语言。我最近发现Logo应该使用动态范围,这对我来说是一个惊喜,因为我一直认为它只是使用了全局变量。这让我想知道是否我不明白动态范围是什么意思。
我思考通过动态范围,变量将进入全局堆栈,因此当您调用另一个方法时,变量仍然可见。 (到目前为止,就像一个全局变量。)然后,如果你声明一个具有相同名称的新变量,这将被推送到全局堆栈,隐藏原始变量。 (此时,与为全局变量分配新值仍然没有太大区别。)最后,当您退出方法时,新的赋值将从堆栈中弹出,变量将恢复为其原始值。 (这似乎是使其成为动态范围的关键部分,而不仅仅是重新分配全局变量。)
所以听说Logo使用了动态范围,我期待这个程序:
to test1
make "x "foo
print (se [In test1: ] :x)
test2
print (se [Back in test1: ] :x)
end
to test2
print (se [In test2: ] :x)
make "x "bar
print (se [Still in test2: ] :x)
end
test1
获得此输出:
In test1: foo
In test2: foo
Still in test2: bar
Back in test1: foo
但是当我在FMSLogo中运行它时,它实际上有这个输出:
In test1: foo
In test2: foo
Still in test2: bar
Back in test1: bar
这实际上与我小时候的记忆相符,如果有一个名为x
的全局变量,则与我期望的一致。但我不知道这是动态范围 - 变量永远不会超出范围!
那么为什么像this one这样的引用声称Logo使用动态范围?
答案 0 :(得分:3)
Logo确实有动态范围,但您的示例没有局部变量,因此在test2
函数中设置的变量是全局变量。您需要使用local
关键字而不是make
关键字来创建局部变量。
这应该展示动态范围:
to test1 :x
test2
end
to test2
print (se [In test2: ] :x)
end
make "x "foo
test2
test1 "bar
如果我做对了(自从我写了任何徽标以来大约二十年),它应该产生:
In test2: foo
In test2: bar
直接调用test2
函数使用全局变量,但是从test1
调用时,它将使用传递给test1
的参数而不是全局变量。