我正在尝试替换列表中的变量:
% set a 1
1
% set b {1 $a}
1 $a
%
% set a 1
1
% set b [list 1 $a]
1 1
当我使用花括号{}
来定义列表时,变量 'a' 不会被其值替换,但在使用list
它的情况下会被替换。
使用定义的列表时如何替换变量的值{}
?
我正在尝试替换列表中的变量:
% set a 1
1
% set b {1 $a}
1 $a
%
% set a 1
1
% set b [list 1 $a]
1 1
当我使用花括号{}
来定义列表时,变量 'a' 不会被其值替换,但在使用list
它的情况下会被替换。
使用定义的列表时如何替换变量的值{}
?
% set a 1
1
% subst {1 $a}
1 1
% set b [subst {1 $a}]
1 1
但是大多数 Tcl:ers 实际上更喜欢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
文档: list , set , subst , Tcl 语言语法总结
使用 {} 定义的列表时如何替换变量的值?
简而言之,你没有。
{}
真正做的是定义一个未替换的字符串。可以将其解释为列表,但也可以是其他内容,例如脚本。所有这些都是 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
and regexp
; subst
可能会出什么问题?)只要list
正确使用,好吗?