关于Tcl中命名空间的问题

3 namespaces export tcl

我在Tcl中有两个关于命名空间的问题.

namespace eval ::dai {
         set a 5
         set b 10
         namespace export *
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  1. export *- 导出会使这个命名空间内的一些变量可以用在其他命名空间中,但这是什么export *意思?

  2. 设置5,我们不应该使用variable a 5?他们是一样的吗?一些教程说在命名空间内部,我们应该使用variable,命名空间variableset命名空间之间有什么区别?

kos*_*tix 7

1)对于Unix用户来说(原本应该是)合乎逻辑的,"*"表示"目前可用的一切".就像你rm -f *在shell中做的那样,shell扩展了"*"并用当前目录中存在的所有文件的列表替换它.实际上,作为namespace手动状态,您可以指定比简单的"*"更精细的图案.要了解那些"全球式"提到的东西,那就意味着阅读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
Run Code Online (Sandbox Code Playgroud)

namespace手册页"NAME RESOLUTION"部分中有说明.

请注意,此行为可能出现不合逻辑,但它实际上匹配的程序范围的:如果你set foo bar在过程体,这意味着设置局部变量,除非另有说明使用两种globalvariable或使用完全限定域名(像::ns::foo) .

  • _Always_**使用`variable`在namespaces_中声明**_variables.如果碰巧有一个具有相同名称的全局变量,则不这样做会引起很多混淆.声明后,您可以随意做任何事情.但是,`namespace export`(和`namespace import`)只能用于命令; 变量的等价物是使用带有`variable`,`upvar`或`namespace upvar`的完全限定的变量名. (2认同)