我想将在一个函数中获得的变量参数传递给另一个函数,但我无法这样做。函数获得偶数个变量参数,然后必须将其转换为数组。下面是示例。
程序abc1
得到两个参数( k k
)而不是形成 abc1
程序这些必须传递给 proc abc
其中列表到数组的转换要完成。列表到数组转换在 proc1 中有效,即 abc1
但不在第二个过程中,即 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
输出:
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)
最佳答案
最佳解决方案:扩展替换
正确的方法是确保外部过程(在堆栈方面)正确调用内部过程;如果需要多个参数,那就应该提供。随着 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]
}
所有
{*}
确实是说单词的其余部分应该被分解(使用列表语法规则)并用作多个参数,而不是 Tcl 的默认“一个视觉单词形成单个单词”规则。这是理想的选择。旧解决方案:Eval 命令
如果您出于某种原因仍在使用旧版本的 Tcl(即 Tcl 8.4 或之前版本),那么您可以使用
eval
命令而不是上述语法:eval abc $l2
对于上述
eval
,有一些更有效的方法。 ,您可能会在旧代码中看到;例如:eval [linsert $l2 0 abc]
eval [list abc] [lrange $l2 0 end]
# ... etc ...
但实际上,它们都被
abc {*}$l2
淘汰了。它更短,更容易编写,而且速度更快。 (它只是在 8.4 或更早版本中不可用,而且还有太多部署尚未升级。)如果可以,请使用扩展语法。事实上,8.5 及更高版本的惯用 Tcl 代码几乎不需要 eval
;这在多大程度上被证明是正确的,甚至对语言的维护者来说是相当令人惊讶的。
关于tcl - 如何在tcl中将变量参数从一个函数传递给另一个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4560668/