谁能让我知道TCL upvar 0
和upvar 1
TCL 之间的区别,我们如何实时使用.但是,如果有人用例子解释,它会让我更清楚.
Don*_*ows 10
当你调用一堆程序时,你会得到一堆堆栈帧.它就在名字中.我们可能会这样想象:
abc 123 456 bcd 321 456 cde 654 321
好了,我们已经得到了abc
主叫bcd
通话cde
.简单.
该0
和1
在upvar
说多少级仰视变量链接到时候去堆栈.1
意味着进入上一层(即,在主叫用户当前帧的),从说cde
要bcd
在我们的例子中,2
会去从cde
多达abc
并3
一路攀升到全球评价水平,整体脚本和回调运行.0
这是一个特例; 它意味着在当前堆栈帧中进行查找.还可以通过放在#
名称前面来使用堆栈底部的索引,因此#0
指示全局框架,#1
它首先调用它.
最常见的用途upvar
是upvar 1
(如果你离开了水平,那就是它的作用).upvar 0
只有在想要为变量获得不同的(通常更容易使用)名称时才会使用它.下一个最常见的一个是upvar #0
,虽然global
是一个更常见的简写(为方便起见,它匹配名称的不合格部分).其他形式很少见; 例如,upvar 2
通常表示真正令人困惑和纠结的代码,几乎没有人upvar #1
在Tcl 8.6的协程之前使用过.我从未见过upvar 3
或upvar #2
在野外(尽管计算级别指标存在于Tcl的某些对象系统中).
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
Run Code Online (Sandbox Code Playgroud)
upvar 0
- 简化变量名称:proc remember {name contents} {
global my_memory_array
upvar 0 my_memory_array($name) var
if {[info exist var]} {
set var "\"$var $contents\""
} else {
set var "\"$name $contents\""
}
}
remember x 123
remember y 234
remember x 345
remember y 456
parray my_memory_array
# my_memory_array(x) = ""x 123" 345"
# my_memory_array(y) = ""y 234" 456"
Run Code Online (Sandbox Code Playgroud)
好吧,我认为一个例子可以让差异变得很清楚:
假设我们有一个函数 test_upvar1:
proc test_upvar1 {} {
upvar 1 a b
incr b
}
Run Code Online (Sandbox Code Playgroud)
还有一个函数 test_upvar0:
proc test_upvar0 {} {
upvar 0 a b
incr b
}
Run Code Online (Sandbox Code Playgroud)
现在我们设置变量 a 并调用这两个函数来看看会发生什么:
set a 5
test_upvar1
Run Code Online (Sandbox Code Playgroud)
这将返回 6
set a 5
test_upvar0
Run Code Online (Sandbox Code Playgroud)
将返回 1
发生这种情况是因为我们用 0 和 1 选择我们的执行帧 0 链接在同一执行帧 1 上一个帧。