5

我创建了从项目到项目处理程序的映射。

  array set handlers {
             handleItem1 handlerFunction1
             handleItem2 handlerFunction2
  }

但是 handlerFunctions 可以带参数。

所以下面的代码是行不通的。

 if { [info exists handlers($item) ] } {
       eval $this $handlers($item)
 }

那么我可以更改此代码以调用可以获取参数的处理程序吗?

4

1 回答 1

7

有几种选择:

  • 命令前缀如果您使用的是 Tcl 8.5 或更高版本(8.4 处于其生命周期的尽头,请尽可能升级),那么命令扩展 with{*}是最好的方法。

    proc putargs args {puts $args}
    set callback {putargs CALLBACK}
    # Invoke it
    {*}$callback param1 param2 ;# prints CALLBACK param1 param2
    
  • 脚本片段Eval 回调,但在末尾添加额外的单词。(跟踪这样做)

    proc putargs args {puts $args}
    set callback {putargs CALLBACK [clock seconds]}
    # Invoke
    eval $callback [list param1 param2] ;# Prints CALLBACK 1369834114 param1 param2
    

    允许像这样的 hackset callback {puts "CALLBACK" ;#}将忽略该行的其余部分,但速度较慢。

  • 命令不是很有用,因为你不能传递任何东西。

    proc putargs args {puts $args}
    set callback {putargs CALLBACK}
    # Invoke
    {*}$callback ;# prints CALLBACK
    
  • 脚本参数在当前范围内作为变量传递,有时也使用字符串替换(Tk 这样做)

    proc putargs args {puts $args}
    set callback {putargs CALLBACK $param1 $param2}
    # Invoke
    set param1 FOO
    set param2 BAR
    eval $callback ;# prints CALLBACK FOO BAR
    
  • 命令名称与命令前缀类似,但不进行扩展。(Tcllib 的 SASL 为自己的机制做到这一点)。不建议。

    proc putargs args {puts $args}
    set callback putargs
    # Invoke
    $callback param1 param2
    

具有最佳性能的最佳解决方案是命令前缀。

于 2013-05-29T13:39:19.237 回答