我已经定义了变量的过程,然后按照该步骤延迟使用变量。
问题在于延迟命令在执行命令时而不是在给出命令时处理变量。考虑以下示例:
该代码尚未经过测试,但无论如何要点很明确:
for {set i 0} {$i < 100} {incr i} {
set outputItem $i
set time [expr 1000+100*$i]
after $time {puts "Output was $outputItem"}
}
我希望打印以下内容:
Output was 1
Output was 2
Output was 3
...
但实际上它会打印:
Output was 100
Output was 100
Output was 100
我猜这表明,在启动after命令后,tcl会保留参数名称(而不是变量的值)。
有什么方法可以将变量名替换为变量内容,以便延迟命令(在xxx yyy之后)可以按需工作?
答案 0 :(得分:1)
问题是这一行:
after $time {puts "Output was $outputItem"}
$outputItem
的替换发生在after事件触发时,而不是在您定义它时。 (大括号可以防止其他任何事情。)要获得所需的内容,您需要列表引用,这是通过list
命令完成的:
after $time [list puts "Output was $outputItem"]
list
命令生成列表和预替换命令(由于Tcl语法的定义方式)。 很棒用于构建您以后将要调用的东西。我想它也可能被称为make-me-a-callback
,但是后来人们会想知道它在创建列表中的用途。两者都做。
如果您的回调需要两个或多个命令,请使用帮助程序(或apply
)将其包装为一个命令;尽力减少使回调与多个直接命令一起使用的困惑是完全值得的。