我正在尝试替换列表中的变量:
% set a 1
1
% set b {1 $a}
1 $a
%
% set a 1
1
% set b [list 1 $a]
1 1
当我使用花括号{}
时,为了定义列表,变量'a'不会被其值替换,但是如果使用list
,则确实如此。
在使用{}
定义的列表时,如何替换变量的值?
答案 0 :(得分:2)
% set a 1
1
% subst {1 $a}
1 1
% set b [subst {1 $a}]
1 1
但大多数Tcl:在创建带替换的列表值时,实际上更喜欢使用list
,例如在第二次尝试中:
% set b [list 1 $a]
这样做的一个原因是subst
不会保留值中的列表结构:
% set a {a b}
a b
% set b [subst {1 $a}]
1 a b
% set b [list 1 $a]
1 {a b}
另一种可能性是使用双引号而不是括号;这也不会保留列表结构。
% set b "1 $a"
1 a b
答案 1 :(得分:1)
在使用使用{}?
定义的列表时,如何替换变量的值
简而言之,你没有。
{}
真正所做的是定义一个未取代的字符串。有可能将其解释为列表,但也可能是其他内容,例如脚本。这是Tcl基本性质的一部分,它就是所有这些。
如果您希望替换变量,则使用不同类型的引用,或者通过subst
运行结果(定义为对字符串起作用)。这些天最常用于列表的“引用”是list
命令,因为它正确地保留了元素边界。
我认为可以使用各种字符串操作来创建一个可以根据需要对字符串进行后处理的命令,但这将是缓慢而复杂的:
proc substList {string} {
# Add backslashes in front of metacharacters
set safer [string map {\\ \\\\ [ \\[ ] \\]} $string]
# Convert variable mentions to our “safe” version
regsub -all {\$\w+} $safer {[list &]} tmpl
# Do the substitutions in the caller's context
tailcall subst $tmpl
}
快速测试:
% set a "1 2 3"
1 2 3
% set b {x $a}
x $a
% substList $b
x {1 2 3}
似乎在这个简单的情况下工作,虽然我不想保证它实际上是正确的。 (毕竟,它正在使用string map
和 regexp
和 subst
;可能出现什么问题?)只需使用{{1好的,好吗?