名字空间(namespace)
时间:2010-03-16 来源:hs272307562
命名空间的存在是为了对两个可能引起混淆的东西进行分类以示区别。
常见的情况之一,比如某个变量名字,大家都很喜欢用,可又不希望彼此影响,就可以用命名空间进行区分。命名空间本质上是给事物限定一个范围。比如城市A的张三和城市B的张三,要是不通过“城市A”和“城市B”这样的范围来加以明确的话,谁知道究竟是指那个张三呢。
基本用法:
namespace eval myspace {
variable var_tmp "haha"
} ; # 创建一个命名空间(namespace)
set var_name "value 1"
set myspace::var_name "value 2" ; # 通过使用"::"连接空间名字和变量名
set myspace::var_tmp "haha 2" ;
puts $::var_name ; 默认的命名空间为空字符 ""
proc myspace::echo {msg} {
puts "== $msg"
} ; # 函数也可以有不同的命名空间
namespace eval myspace::subspace {} ; # 命名空间可以嵌套
set myspace::subspace::var_name "value 3"
有了命名空间,就可以使用自己喜欢的变量名或者函数名而不用担心与他人的程序代码冲突了。当然你的命名空间的名字必须是不同于他人的。根据Java里包(package)的命名建议,推荐使用倒序的URI。比如,我可以写
namespace eval net::noyesno {
# This is my namespace
proc echo {msg} { puts "noyesno.net: $msg"}
}
不过Tcl里面的namespace的功能要强大的多。
命名空间的创建、删除和查询
- 创建 namespace eval ::a::b {}
- 删除 namespace delete ::a::b ::a::c
- 当前空间 namespace current
- 是否存在 namespace exists ::a::b
- 查询子空间。namespace children ?which? ?pattern?
- 查询父空间。namespace parent ?which?
命名空间的使用
namespace eval ::a::b $script $x $y $z
在指定的命名空间中执行命令 $script $x $y $z
namespace inscope ::a::b $script $x $y $z
在指定的命名空间中执行命令 $script [list $x $y $z] 。和 namespace eval 很像,只是对第一个参数之后的参数处理不同。
主要用于 namespace code,一般不直接使用这条命令。
namespace code script
返回一个包装好的命令,从而在调用时可以不用指定命名空间。参考下面的例子可以理解。
namespace eval ::t {
proc dump { args } {
puts [list [llength $args] $args]
}
proc ref_dump {} { return [namespace code {dump 3}]}
}
namespace eval ::t {dump 3 {4 5}} ; # 2 {3 {4 5}}
namespace eval ::t dump 3 {4 5} ; # 3 {3 4 5}
namespace inscope ::t dump 3 {4 5} ; # 2 {3 {4 5}}
namespace inscope ::t {dump 3 {4 5}} ; # 2 {3 {4 5}}
set script [::t::ref_dump]
$script 3 {4 5} ; # 3 {3 4 5}
puts $script
::namespace inscope ::t {dump 3} ; # 这是 proc 的名字
两个 namespace 之间进行命令引用
- namespace export ?-clear? proc_name_pattern
- namespace import ?-force? proc_name_pattern
- namespace forget proc_name_pattern
- namespace origin proc_name
namespace 在 Tcl 中常被用来表示库(library)或包(package)。通过 namespace import 把别的库中的命令导入到当前空间,从而可以直接使用相关命令,而无需再添加命名空间前缀。
命名空间名字的操作
- namespace qualifiers ::a::b::c ; # 返回 ::a::b
- namespace tail ::a::b::c ; #返回 c
- namespace which ?-command? ?-variable? name 查询命令或者变量的完整名称,类似于 shell 命令 which
相关阅读 更多 +