TCL:如果数组名称也是变量,我如何检查数组的信息

时间:2017-12-14 09:13:44

标签: tcl

我无法检查我的数组是否存在,数组名称是否在变量中。在我的例子中,数组名称也包含空格。

code snippet:  
array set a\ b{  
    key1 "val1"  
}  

proc checkArr {name}
{
    if {![info exists $name($key)]} {  
       return {}  
    }
}

checkArr "a b"

错误:无法读取“name(key1)”:变量不是数组

有人可以帮忙吗?

2 个答案:

答案 0 :(得分:2)

您的代码的主要问题是,您正在尝试查看数组是否存在于本地范围内,而它存在于全局范围内。

array set a\ b {
  key1 "val1"
}

proc checkArr {name} {
  upvar $name arr
  if {![info exists arr(key1)]} {
    return 0
  } else {
    return 1
  }
}

为了在proc的本地范围内访问数组,您可以使用global $nameupvar $name arr(我使用上面的后者),或者您可以使用uplevel执行info exist部分时。

我对代码进行了一些其他调整:

  • array set部分添加了空格,否则您只为该功能提供一个参数
  • $name($key)更改为arr(key1)info exists采用变量名称,因此如果您使用$name($key),它会尝试查找该变量值的变量名称(如果$name($key)的值为' value& #39;,info exists会尝试查明名为value的变量是否存在,但数组值$name($key)不存在,因此您会收到错误消息。)

答案 1 :(得分:0)

让我们创建一个命令来检查是否存在全局数组:

proc checkArr name {
    uplevel #0 [list info exists $name]
}

% checkArr "a b"
0

当给定"a b"作为参数时,此命令执行脚本info exists {a b},但不执行命令中的本地级别:uplevel #0部分表示脚本在全球水平。

现在我们创建数组,并检查它:

% array set a\ b {key1 val1}
% checkArr "a b"
1

它存在。我们还可以使用相同的代码检查数组成员是否存在:

% checkArr "a b(key1)"
1

实际上,任何类型的字符串都可以传递给checkArr,它会告诉你是否有一个带有该名称的变量(数组或其他)。如果你想要一个专门的数组成员检查器,可以这样写:

proc checkArrayMember {arrName memberName} {
    uplevel #0 [list info exists $arrName\($memberName)]
}

% checkArrayMember "a b" key1
1

左括号前面的反斜杠删除了它的句法含义,使它只是字符串的一部分:脚本基本上变为info exists {a b(key1)}

文档: arrayinfolistprocuplevelSummary of Tcl language syntax