vai*_*war 4 tcl variadic-functions
我想将在一个函数中获得的变量参数传递给其他函数,但我无法这样做.函数获得偶数个变量参数,然后必须在数组中转换.以下是示例.
过程abc1获取两个参数(k k)而不是表单abc1过程,这些必须传递给proc abc,其中list要进行数组转换.列表到数组转换在proc1中工作,abc1但不在第二个proc中工作abc
获得的错误如下
proc abc {args} {
puts "$args"
array set arg $args
}
proc abc1 {args} {
puts "$args"
array set arg $args
set l2 [array get arg]
abc $l2
}
abc1 k k
abc k k
Run Code Online (Sandbox Code Playgroud)
输出:
k k
{k k}
list must have an even number of elements
while executing
"array set arg $l1"
(procedure "abc" line 8)
invoked from within
"abc $l2"
(procedure "abc1" line 5)
invoked from within
"abc1 k k"
(file "vfunction.tcl" line 18)
Run Code Online (Sandbox Code Playgroud)
Don*_*ows 13
正确的方法是确保外部过程(以堆栈术语)正确地调用内部过程; 如果预期有多个参数,那就是应该提供的参数.随着Tcl 8.5的出现,使用一种称为扩展替换的语言语法非常简单:
proc abc1 {args} {
puts "$args"
array set arg $args
set l2 [array get arg]
abc {*}$l2
# Or combine the two lines above into: abc {*}[array get arg]
}
Run Code Online (Sandbox Code Playgroud)
所有这些{*}都是说应该分解其余部分(使用列表语法规则)并用作多个参数而不是Tcl的默认"一个视觉词形成一个单词"规则.这是理想的.
如果由于某种原因(即Tcl 8.4或之前)仍在使用旧版本的Tcl,那么您使用eval命令而不是上述语法:
eval abc $l2
Run Code Online (Sandbox Code Playgroud)
对于上述方法,有一些更有效的方法eval,您可能会在旧代码中看到这些方法; 例如:
eval [linsert $l2 0 abc]
eval [list abc] [lrange $l2 0 end]
# ... etc ...
Run Code Online (Sandbox Code Playgroud)
但实际上它们都变得过时了abc {*}$l2,更短,更简单,写得更快.(它仅在8.4或之前不可用,并且有太多部署尚未升级.)如果可以,请使用扩展语法.事实上,8.5及以后的惯用Tcl代码几乎不需要eval; 事实证明这一点的真实程度对语言的维护者来说甚至相当令人惊讶.