首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >tcl中的upvar命令和全局命令有什么实际区别

tcl中的upvar命令和全局命令有什么实际区别
EN

Stack Overflow用户
提问于 2009-02-27 20:15:44
回答 4查看 5.5K关注 0票数 1

我是TCL的新手,正在为其他人开发的一些代码提供QA (不是真的!)。在这个特定的程序中有很多很多的全局变量,我有时会看到upvar,通常与global一起使用。我知道upvar模拟的是按引用传递,但是下面这两个过程之间的实际区别是什么?

代码语言:javascript
复制
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会更干净。我是不是漏掉了什么?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-03-09 11:30:10

代码语言:javascript
复制
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”设置为堆栈的上一帧。

要查看以下内容:

代码语言:javascript
复制
myFirstProc $myBigFatGlobalVariable 3
puts $hello ;# ==> 9
unset hello
mySecondProc 3
puts $hello ;# ==> can't read "hello": no such variable

如果您真的想从mySecondProc设置全局"hello“,则需要添加global $myBigFatGlobalVariable

票数 2
EN

Stack Overflow用户

发布于 2009-02-27 20:49:06

它们很相似,但又有细微的不同。

upvar允许您访问调用堆栈中x级以上的变量。它们不一定是全局变量。

您可以使用upvar通过传递upvar #0 varName localVarName来模拟全局变量,在这种情况下,您将获得带有本地名称的全局变量。

要模拟按引用传递,您需要传递变量的名称,然后对该名称调用upvar。

如果您知道变量的名称,则可以按原样使用它。

遵循以下代码:

代码语言:javascript
复制
    # 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

这将返回

代码语言:javascript
复制
    Level 1: bowow niegh meow
    Level 2: moo beta
    Global : japan

upvar只是从调用堆栈中获取变量的一种方法。(调用函数)包括“global”堆栈。

票数 4
EN

Stack Overflow用户

发布于 2009-02-27 20:36:38

不同之处在于,upvar 1 $var local使local从上面级别的$var中命名的变量中获取其值。因此,在myBigFatGlobalVariable中,不必在全局范围内定义$var。

代码语言:javascript
复制
proc p1 { var1 } {
upvar 1 $var1 local1
puts $local1
}

proc p2 { } {
set local2 "local2"
p1 local2
}

set global1 "global1"
p1 global1
p2

p1将从调用堆栈中位于其上的级别1打印出var1的值。全局变量总是在顶层定义的,所以upvar #0和全局变量做同样的事情。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/596474

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档