我是TCL的新手,正在为其他人开发的一些代码提供QA (不是真的!)。在这个特定的程序中有很多很多的全局变量,我有时会看到upvar,通常与global一起使用。我知道upvar模拟的是按引用传递,但是下面这两个过程之间的实际区别是什么?
set myBigFatGloblVariable "hello"
proc myFirstProc { var1 var2 } {
upvar 1 $var1 local
set local [expr $var2 * 3]
}
proc mySecondProc { var2 } {
global myBigFatGlobalVariable
set $myBigFatGlobalVariable [expr $var2 * 3]
}
myFirstProc $myBigFatGlobalVariable 3
mySecondProc 3在我看来,myFirstProc会更干净。我是不是漏掉了什么?
发布于 2009-03-09 11:30:10
set myBigFatGlobalVariable "hello"
proc myFirstProc { var1 var2 } {
upvar 1 $var1 local
set local [expr $var2 * 3] }
proc mySecondProc { var2 } {
global myBigFatGlobalVariable
set $myBigFatGlobalVariable [expr $var2 * 3] }
myFirstProc $myBigFatGlobalVariable 3
mySecondProc 3两个进程之间的最大区别在于: myFirstProc将全局设置为"hello",mySecondProc将本地设置为"hello“。
mySecondProc引用全局myBigFat...来获取值"hello",但不会改变"hello“变量的作用域。
myFirstProc接收值"hello“作为参数,然后在堆栈上一帧名为"hello”的变量和本地变量" local“之间创建一个链接。设置"local“的效果是将"hello”设置为堆栈的上一帧。
要查看以下内容:
myFirstProc $myBigFatGlobalVariable 3
puts $hello ;# ==> 9
unset hello
mySecondProc 3
puts $hello ;# ==> can't read "hello": no such variable
如果您真的想从mySecondProc设置全局"hello“,则需要添加global $myBigFatGlobalVariable
发布于 2009-02-27 20:49:06
它们很相似,但又有细微的不同。
upvar允许您访问调用堆栈中x级以上的变量。它们不一定是全局变量。
您可以使用upvar通过传递upvar #0 varName localVarName来模拟全局变量,在这种情况下,您将获得带有本地名称的全局变量。
要模拟按引用传递,您需要传递变量的名称,然后对该名称调用upvar。
如果您知道变量的名称,则可以按原样使用它。
遵循以下代码:
# here there is only 1 global variable, but we also need to access to variables defined in the calling functions
proc p3 {} {
# upvar defaults to 1, so not needed to put in here
# also notice you can call upvar on more than one variable
upvar dog myDog horse myHorse cat myCat
upvar 2 cow myCow alpha myAlpha
upvar #0 samurai mySamurai
puts "Level 1: $myDog $myHorse $myCat"
puts "Level 2: $myCow $myAlpha"
puts "Global : $mySamurai"
}
proc p2 {} {
set dog "bowow"
set horse "niegh"
set cat "meow"
p3
}
proc p1 {} {
set cow "moo"
set alpha "beta"
p2
}
set samurai "japan"
p1这将返回
Level 1: bowow niegh meow
Level 2: moo beta
Global : japanupvar只是从调用堆栈中获取变量的一种方法。(调用函数)包括“global”堆栈。
发布于 2009-02-27 20:36:38
不同之处在于,upvar 1 $var local使local从上面级别的$var中命名的变量中获取其值。因此,在myBigFatGlobalVariable中,不必在全局范围内定义$var。
proc p1 { var1 } {
upvar 1 $var1 local1
puts $local1
}
proc p2 { } {
set local2 "local2"
p1 local2
}
set global1 "global1"
p1 global1
p2p1将从调用堆栈中位于其上的级别1打印出var1的值。全局变量总是在顶层定义的,所以upvar #0和全局变量做同样的事情。
https://stackoverflow.com/questions/596474
复制相似问题