Array的意思是“数组”,而Tcl中的array实际上被称为map更合适。Tcl中的list则实际上相当于数组。
map的主要特点是存储键值对,即一个索引对应一个值。相当于perl里面的哈希表(hash table)。
Tcl中有两种办法给array赋值:array命令或者set命令。
array set ta [list a 1 b 2] ; # 同时存储了两个键值对 set ta(c) 3 ; # 结果是array ta的值相当于 a=>1, b=>2, c=>3
相对应的获取array中元素值的获取也有两种办法:
set v [lindex [array get ta a] 1] ; # 注意这里使用了lindex命令 set v $ta(a)
array get命令实际上同时返回了索引和值。这看起来好像显得有些不方便,但如果要同时处理多个元素,就会显出它的方便来了。
foreach {k v} [array get ta *] {
puts [list $k $v]
}
命令array get实际上是使用通配符来匹配键值的。
如果要删除array中的某些值,可以用命令array unset name b。这个命令同样支持通配符,因此要清空array的话,就可以用array unset *。
如果要只获取array中所有的键值(索引),可以用命令array names *。
如果要判断一个变量是不是array,可以用命令 array exists name
那怎么删除整个数组呢?数组的名字和普通变量的名字享有同样的命名空间,因此
unset命令Tcl中的array是不可以用作proc的参数,也不可以作为返回值的,即下面的例子是会出错的。
array set ta [list a 1 b 2 c 3]
proc f {r} {
puts $r(b)
array set tb [list a 3 b 4 c 5]
return $tb ; # 不可以直接返回array
}
set rv [f $ta] ; # 不可以直接传递array作为参数
解决办法有两种,一种是利用list对array进行转换;另一种是把数组声明在函数外部(利用namespace或者upvar)。
proc f {r} {
array set rr $r ; # list转换为array
puts $rr(b)
array set rr [list a 3 b 4 c 5]
return [array get rr *] ; # array转换为list
}
array set ta [list a 1 b 2 c 3]
array set rv [f [array get ta *]] ; # 利用list对arrray进行转换
proc f2 {name} {
upvar $name rr ; # 映射外部变量为局部变量
puts $rr(b)
uplevel [list array set $name [list a 3 b 4]] ; # 赋值到上一层frame中
}
array set ta [list a 1 b 2 c 3]
f2 ta ; # 传递array的名字作为参数
Tcl中允许数组的名字为空,这就构成了一个特殊的空数组。比如 set (a) 1 或者 array set :: {a 1 b 2}。
Tcllib中用来实现面向对象(class)的stooop就利用空数组这一特性。