tcl - 如何在tcl中将变量参数从一个函数传递给另一个函数

标签 tcl variadic-functions

我想将在一个函数中获得的变量参数传递给另一个函数,但我无法这样做。函数获得偶数个变量参数,然后必须将其转换为数组。下面是示例。

程序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/

相关文章:

c++ - 创建自定义 tcl channel 驱动程序时出现段错误

variables - 错误: Can't read "n" : no such variable in tcl

tcl - 是否有 "native"方法将 Tcl 中的数字转换为 dB

scala - 将变长参数传递给期望相同的另一个函数?

tcl - 如何在期望控制台日志文件中添加时间戳

shell - 将文件读入 String 并在 Expect Script 中执行循环

javascript - webpack/lib/Compiler.js 中的意外标记应用 : util. deprecate((...args) => {

php, invokeArgs : parameters changed, 怎么返回呢?

c - C 中带有可变参数的函数的包装

c - main 中的可变参数列表