TCL数组索引-规范是什么

TCL数组索引-规范是什么,tcl,Tcl,我碰巧遇到这样的情况: set a(()) 100 它由TCL解释器获取,并添加到数组a中,该数组是一个索引为()且值为100的元素 我很困惑。数组索引没有太多说明,它可以接受任何字符。那很好。问题是,如何检索它 放入$a(())不起作用: can't read "a(()": no such element in array 解决办法是: set i () puts $a($i) 或 当“a(())”被愉快地拿走,但却找不到时,$a(())为什么不起作用,我正在努力弄清楚这一点 你能帮忙

我碰巧遇到这样的情况:

set a(()) 100
它由TCL解释器获取,并添加到数组
a
中,该数组是一个索引为()且值为100的元素

我很困惑。数组索引没有太多说明,它可以接受任何字符。那很好。问题是,如何检索它

放入$a(())
不起作用:

can't read "a(()": no such element in array
解决办法是:

set i ()
puts $a($i)

当“
a(())
”被愉快地拿走,但却找不到时,
$a(())
为什么不起作用,我正在努力弄清楚这一点

你能帮忙吗?或者这是我们仅仅认识到并接受它的东西吗?

a(())
是数组成员的有效名称,正如您所说,我们可以使用
set
为其赋值并检索其值:

set a(()) 100
set a(())
调用
set
命令时,与所有命令一样,解释器首先将命令行拆分为单词,根据需要执行替换,然后将这些单词作为参数传递给命令。
set
的第一个参数是变量名:
set
命令使用与该名称关联的变量,或者在赋值时创建一个新变量,或者如果在检索时找不到任何此类变量,则会引发错误

$
语法对于单个参数
set
来说主要是语法上的甜点,但不一定只使用一个命令行单词作为变量名。当解释器找到一个未转义的
$
时,它尝试查找组成变量名的字符序列,然后用变量的值替换
$
和名称。在这之后,单词可以包含更多文本,并且单词不必以
$
开头

解释器小心地避免过度匹配,因此只允许有限的字符集,一旦发现非法字符,解释器就会停止并尝试使用找到的字符进行替换。如果找到了一个左括号,匹配会稍微放松(因为它可以期望以右括号的形式找到一个结束标记),这样就可以在索引中执行不同类型的替换(这就是为什么
set i();put$a($i)
有效的原因)

在这种情况下,如果单词结束(即找到空格;由于变量名格式错误,替换将失败)或找到右括号,则匹配将停止。这就是为什么
$a(())
失败的原因:解释器尝试使用
a(()
作为变量名,后跟
作为单词中的下一个字符
$a(\)
确实有效,因为转义右前括号会否定其语法含义

如果
$
后面的第一个字符是一个大括号,则匹配的右大括号之前的所有字符都将用作变量名,这意味着圆括号内不能有匹配的右大括号,否则几乎所有字符都会被使用。这意味着
${a(())}
也可以工作

文件:

问题是,如何检索它

问题恰恰在于
$
语法具有限制性。有一些元素名的合法值不能使用
$
表单编写(例如,
()}{()
将极大地混淆解析器!)在这种情况下,你需要使用你列出的另一种技巧。这通常不是一个问题,因为这些尴尬的情况出现的地方是当你没有在脚本的控制下的元素时-既然你为什么会故意选择让自己尴尬?-然后你在做一些事情例如,迭代使用
数组名称查看的名称集,在这种情况下,您已经在变量中获得了值,不会出现问题

有几种方法可以检索该值。以下是我推荐的方法(无特定顺序):

  • 设置值为[设置a(())]
  • set theElementIs();将值设置为$a($theElementIs)
  • upvar 0 a(())别名;将值设置为$alias
  • 还有一个很有效,但不太符合我的口味:

  • 设置值为${a(())}

  • 你为什么要这样做?这怎么会是一个问题?@MoDJ:试图弄清楚一种语言是如何工作的没有错。让我感到羞耻的是,我错误地批准了一次编辑,将[array]标记添加到问题中(我以为我批准了删除标记).Tcl数组与标记引用的数组类型不在同一类别中。请通过拒绝编辑来纠正我的错误。还可以使用
    upvar 0
    为数组元素创建别名(使用简单名称)。
    set a(()) 100
    set a(())