作用域

set alpha 1

proc myproc {} {
    puts $alpha
}

myproc

此程式碼不起作用,因為兩個 alpha 位於不同的範圍內。

命令 set alpha 1 在全域性範圍內建立一個變數(使其成為全域性變數)。

命令 puts $alpha 在命令 myproc 執行時建立的範圍內執行。

這兩個範圍是截然不同的。這意味著當 puts $alpha 試圖查詢名稱 alpha 時,它找不到任何這樣的變數。

但是,我們可以解決這個問題:

proc myproc {} {
    global alpha beta
    puts $alpha
}

在這種情況下,兩個全域性變數 alphabeta 在過程的範圍內連結到別名變數(具有相同的名稱)。從別名變數讀取將檢索全域性變數中的值,並且寫入它們會更改全域性變數中的值。

更一般地說,upvar 命令為來自任何先前作用域的變數建立別名。它可以與全域性範圍一起使用(#0):

proc myproc {} {
    upvar #0 alpha alpha beta b
    puts $alpha
}

別名可以與連結到(alpha)或其他名稱(beta / b)的變數同名。

如果我們從全域性範圍呼叫 myproc,這個變體也可以工作:

proc myproc {} {
    upvar 1 alpha alpha beta b
    puts $alpha
}

範圍編號 1 表示先前範圍呼叫者範圍

除非你真的知道你在做什麼,#001 是與 upvar 一起使用的唯一有意義的範圍。 (upvar 0 為區域性變數建立一個本地別名,而不是嚴格的作用域操作。)

其他一些語言通過花括號定義範圍,讓每個範圍內執行的程式碼檢視周圍範圍內的所有名稱。在 Tcl 中,在呼叫過程時會建立一個單一的作用域,並且只有它自己的名稱可見。如果過程呼叫另一個過程,則其作用域將堆疊在前一個作用域的頂部,依此類推。這意味著與僅具有全域性範圍和區域性範圍(使用子範圍)的 C 風格語言相比,每個範圍充當它已開啟的任何範圍的封閉(但不是立即可見)範圍。過程返回時,其範圍將被銷燬。

文件: globalupvar