我对TCL中的变量范围有疑问,我有以下代码:
namespace eval ::hello {
variable player
variable name
namespace export *
}
proc ::hello::setPlay {value} {
set ::hello::player
}
proc ::hello::getPlay {} {
return $::hello::player
}
proc ::hello::setName {value} {
set ::hello::name
}
proc ::hello::getName {} {
return $::hello::name
}
proc GET_NAME {} {
#here I have a variable called name as well
set name "RON"
return $name
}
在GET_NAME中,如果我将变量名称设置为“RON”,它是否会设置在命名空间中声明的变量名称?我可以在GET_NAME和命名空间中使用相同的变量名吗?如果我在GET_NAME中添加此行variable name
,这是否意味着,它会设置在名称空间中声明的变量?
答案 0 :(得分:5)
过程中的变量(和lambda表达式)默认为该过程的本地变量。如果明确声明为其他内容(例如,使用global
,upvar
或variable
),那么实际将局部变量耦合到其他位置的另一个变量在一个(例如,阅读或写作)完全就像在另一个上行动一样。如果你在其中使用带有::
的变量名,那就是对命名空间变量的引用(全局命名空间只是::
),它可以相对于当前命名空间或全局命名空间来解析,取决于名称是否以::
开始。 (把它想象成文件名中的斜杠。)
在namespace eval
内执行代码时,请始终使用variable
声明变量,然后再使用它们。这避免了全局变量阴影的问题,这些问题非常可怕,但由于某些现有代码依赖于它们而需要保留。 (从技术上讲,你不需要在namespace eval ::
中执行此操作,因为全局变量不能影响自己,但它不会受到伤害。)
处理细节:
在GET_NAME中,如果我将变量名称设置为“RON”,它是否会设置在命名空间中声明的变量名称?
不,不是你写的代码。
我可以在
GET_NAME
和名称空间中使用相同的变量名吗?
您可以在两个地方使用相同的变量名称。这可能令人困惑,但它总体上限制了意外。
如果我在
variable name
中添加此行GET_NAME
,这是否意味着,它会设置在名称空间中声明的变量?
是。确切地说。 (它将两者精确地结合在一起。)