TCL - 带变量的列表

TCL - List with Variables

我在创建包含 TCL 文本和变量混合的列表列表时遇到问题。我有一个用户输入变量,然后我想将其插入列表。为简洁起见,我将跳过用户 select 选项。

set a 0.1
set b 20.0

set c {
    {text1 text2 $a text3}
    {text4 text5 $b text6}
}

foreach i $c {
    set CheckVal [lindex $i 2]
    puts "Threshold is $CheckVal"
}

结果输出:
阈值是 $a
阈值是 $b

期望的输出:
阈值为 0.1
阈值为 20.0

两个备选方案是

set a 0.1
set b 20.0

set c {
    {text1 text2 a text3}
    {text4 text5 b text6}
}

foreach i $c {
    set CheckVal [lindex $i 2]
    puts "Threshold is [set $CheckVal]"
}

存储变量名而不是值,并在puts中通过两步代入($$Checkval不行,但[set $CheckVal]行)得到值调用。

set a 0.1
set b 20.0

set c {
    {text1 text2 $a text3}
    {text4 text5 $b text6}
}

foreach i $c {
    set CheckVal [lindex $i 2]
    puts [subst "Threshold is $CheckVal"]
}

这是双重替换而不是两步替换。看似简单,但subst其实有点棘手,几乎是不得已的技术

无论您使用哪种解决方案,这种将对变量值的引用存储在结构中的方案都是脆弱的,因为它取决于原始变量在范围内并且在取消引用引用时仍然存在。至少,您应该在列表中存储一个限定名称(名称空间和名称)。如果该变量是局部变量,则需要在存储它时的同一调用中使用它(或者使用 upvar 从调用堆栈的更上层开始使用它,但不要去那里)。

虽然 Peter Lewerin 建议的方法有效,但它们只能作为最后的手段使用。通常,您会使用一些对列表进行操作的命令来创建您的列表列表。我相信这就是格伦杰克曼所暗示的。

根据您的实际代码,我可能会使用 list and/or lappend:

set c {}
lappend c \
  [list text1 text2 $a text3] \
  [list text4 text5 $b text6]

然后 foreach 将按照您编写的方式运行。