TCL中upvar 0和upvar 1之间的差异

时间:2015-05-12 11:39:14

标签: tcl upvar

任何人都可以让我知道TCL中Activityupvar 0之间的区别,我们如何实时使用。但是,如果有人用例子解释,它会让我更清楚。

3 个答案:

答案 0 :(得分:10)

当你调用一堆程序时,你会得到堆栈帧的堆栈。它就在名字中。我们可能会这样想象:

abc 123 456
   bcd 321 456
      cde 654 321

好的,我们已abc致电bcd致电cde。简单。

0中的1upvar表示在查找要链接的变量时,堆栈上升了多少级别。 1表示向上一级(即,到当前帧的调用者),在我们的示例中从cdebcd,{{1}从2一直到cdeabc一直到全局评估级别,整个脚本和回调都会运行。 3是一个特殊情况;它意味着在当前堆栈帧中进行查找。还可以通过将0放在名称前面来使用堆栈底部的索引,因此#表示全局帧,#0它调用的第一个东西。

#1最常见的用途是upvar(如果你离开了关卡,那就是它的作用)。 upvar 1仅在您希望为变量获得不同(通常更易于使用)的名称时才使用。下一个最常见的是upvar 0,虽然upvar #0是一种更常见的简写(为方便起见,它与名称的不合格部分相匹配)。其他形式很少见;例如,global通常表示真正令人困惑和纠结的代码,几乎没有人在Tcl 8.6的协程之前使用过upvar 2。我从未在野外见过upvar #1upvar 3(虽然在某些Tcl对象系统中存在计算级别指标)。

upvar #2的示例 - 按名称传递变量:

upvar 1

proc mult-by {varName multiplier} { upvar 1 $varName var set var [expr {$var * $multiplier}] } set x 2 mult-by x 13 puts "x is now $x" # x is now 26 的示例 - 简化变量名称:

upvar 0

答案 1 :(得分:2)

与upvar 1不同,upvar 0为变量创建别名。 例如:

    set a 4 
proc upvar1 {a} {
upvar 1 a b
incr a 4
incr b 3
puts "output is $a $b"
}
proc upvar0 {a} {
upvar 0 a b
incr a 4
incr b 3
puts "output is $a $b"
}
upvar1 $a
puts "in global frame value of a is  $a"

set a 4
upvar0 $a
puts "in global frame value of a is  $a"

输出:

output is 8 7
in global frame value of a is  7
output is 11 11
in global frame value of a is  4

答案 2 :(得分:1)

好的我认为一个例子可以很明显地区别对待:

让我们说我们有一个函数test_upvar1:

proc test_upvar1 {} {
    upvar 1 a b
    incr b
}

一个函数test_upvar0:

proc test_upvar0 {} {
    upvar 0 a b
    incr b
}

现在我们设置变量a并调用这两个函数来看看会发生什么:

set a 5
test_upvar1

这将返回6

set a 5
test_upvar0

将返回1

这是因为我们选择0和1执行帧0链接在相同的执行帧1中更高的帧。

请参阅http://wiki.tcl.tk/1508