循环中的基本TCL变量解引用

循环中的基本TCL变量解引用,tcl,Tcl,我有一个循环,看起来像: foreach x {a b} { set type_$x [some_function_here] set N_$x [function type_$x] } 问题是我想在第二行中取消对类型_u$a的引用,并将其值用作函数参数 但是: set N_$x [function $type_$x] 不起作用,我用subst命令尝试的任何其他组合也不起作用 我如何解决这个问题 set N_$x [function [set type_$x]] $

我有一个循环,看起来像:

foreach x {a b} {
    set type_$x [some_function_here]
    set N_$x [function type_$x]
    }
问题是我想在第二行中取消对类型_u$a的引用,并将其值用作函数参数

但是:

set N_$x [function $type_$x]
不起作用,我用subst命令尝试的任何其他组合也不起作用

我如何解决这个问题

set N_$x [function [set type_$x]]
$var
符号基本上是命令
[set var]
的简写,有时您需要使用命令而不是简写

无法告诉命令求值“当我说“$type_u$x”时,我希望您先计算第一个
$
,直到把整个变量名放在一起”。也就是说,除非您将其编写为
[set type\ux]
,在这种情况下,名称
type\u a
type\u b
首先构造,然后传递给
set


文档:,

三种可能性,按照我认为您应该更喜欢它们的顺序排列

阵列 到目前为止,最简单的方法是使用数组:

foreach x {a b} {
    set type($x) [some_function_here]
    set N($x) [function $type($x)]
}
这确实改变了程序的其他部分看待事物的方式,因此它不是一种零影响技术,但非常简单;我认为这是最值得推荐的方法

本地别名 或者,使用
upvar 0
为名为variable的变量创建本地别名:

foreach x {a b} {
    upvar 0 type_$x typex N_$x Nx
    set typex [some_function_here]
    set Nx [function $typex]
}
在内部,名称只解析为同一个存储单元,因此这是一种有效的技术(尽管
upvar 0
非常棘手!)

单参数
set
最后,您可以使用带有一个参数的
set
命令读取任意命名的变量;
$
语法可以说是这方面的语法糖

foreach x {a b} {
    set type_$x [some_function_here]
    set N_$x [function [set type_$x]]
}

如果你经常这样做,这通常是一种代码味道,它通常表示你应该使用数组。

其他一些方法可以使用动态名称来区分变量

% set x a
a
% set type_$a stackoverflow
stackoverflow
% expr \$type_$a
stackoverflow
% subst $[subst type_$a]

不过,与其他方法相比,这有点复杂

这两种技术都需要运行时重新编译,而且速度会很慢。你也可以加入
eval“string cat\$type_$a”
,以获得一组完美的技术,这是一个坏主意…@Donal Fellows:预计速度会很慢。谢谢你提供的信息。今天再学习一次。