List TCL-带变量的列表

List TCL-带变量的列表,list,tcl,naming-conventions,List,Tcl,Naming Conventions,我在创建包含TCL中的文本和变量的混合列表时遇到了问题。我有一个用户输入变量,然后我想插入到一个列表中。为了简洁起见,我将跳过用户选择选项 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" } 结果输出: 阈值为$

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

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]"
}
存储变量名而不是值,并通过两步替换(
$$Checkval
不起作用,但
[set$Checkval]
起作用)在
puts
调用中获取值

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
和/或
lappend

set c {}
lappend c \
  [list text1 text2 $a text3] \
  [list text4 text5 $b text6]
然后,foreach将按照您编写的方式工作。

阅读并--这些章节中的示例将提供答案。