我在Tcl中有两个关于命名空间的问题。
namespace eval ::dai {
set a 5
set b 10
namespace export *
}
我的问题是:
export *
- 导出会使此命名空间中的某些变量可以在其他命名空间中使用,但这个export *
是什么意思?
设置5,我们不应该使用variable a 5
吗?他们是一样的吗?一些教程说在命名空间内,我们应该使用variable
,命名空间中variable
和set
之间有什么区别?
答案 0 :(得分:7)
1)对于Unix用户来说(原本应该是)合乎逻辑的,“*”表示“目前可用的一切”。就像在shell中执行rm -f *
一样,shell会扩展“*”并将其替换为当前目录中存在的所有文件的列表。实际上,作为namespace
manual states,您可以指定比简单的“*”更精细的图案。要了解那里提到的“全球式”事物的含义,请阅读string match
。
2)“我们不应该使用......”的问题是不正确的,因为这取决于你想做什么。如果要声明位于命名空间中的变量,请使用variable
。如果要设置变量,请使用set
,但是如果命名空间中不存在该变量x
,则Tcl将尝试使用此名称查找全局变量,请参阅:
% set x 5
5
% namespace eval foo {
set x 10
}
10
% set x
10
# ^^ observe that the global variable has been assigned
% namespace eval foo {
variable x
set x 20
}
20
% set x
10
# ^^ observe that now `set x 20` found the variable `x` in the namespace and assigned to it
"NAME RESOLUTION" section of the namespace
man page中解释了这一点。
请注意,此行为可能看似不合逻辑,但它实际上与过程范围的行为相匹配:如果您在过程体中执行set foo bar
,则表示设置 local 变量,除非您声明否则使用global
或variable
或使用完全限定名称(例如::ns::foo
)。
答案 1 :(得分:2)
namespace export
仅适用于命名空间中的命令(即proc
s):它将它们注册为有资格导入另一个命名空间。例如:
% package require textutil
0.7.1
% textutil::splitx abcdefghij {[aeiou]}
{} bcd fgh j
% splitx abcdefghij {[aeiou]}
invalid command name "splitx"
while evaluating {splitx abcdefghij {[aeiou]}}
% namespace import textutil::*
% splitx abcdefghij {[aeiou]}
{} bcd fgh j