我无法检查我的数组是否存在,数组名称是否在变量中。在我的例子中,数组名称也包含空格。
code snippet:
array set a\ b{
key1 "val1"
}
proc checkArr {name}
{
if {![info exists $name($key)]} {
return {}
}
}
checkArr "a b"
错误:无法读取“name(key1)”:变量不是数组
有人可以帮忙吗?
答案 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 $name
或upvar $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)}
。
文档: array, info, list, proc, uplevel, Summary of Tcl language syntax