Tcl proc 參數是 pass by value 的:
proc printName {employeeName} {
puts "employeeName = $employeeName"
}
set name "cooper maa"
printName $name如你所預期的,上列這段 Script 的輸出是:
employeeName = cooper maa
假若你將 Script 改成這樣,結果會是一樣的:
proc printName {varName} {
# 宣告一個區域變數 employeeName,employeeName 變數是上一層 的某個變數的分身
upvar $varName employeeName
puts "employeeName = $employeeName"
}
set name "cooper maa"
printName name我們都知道,Tcl 是不必宣告變數的,要產生新變數,隨時 set 一下就行。upvar 是故意來「破壞規矩」的指令,它的目的就是宣告變數用的!
上列 Script 中:
upvar $varName employeeName
這行指令是個倒裝句,它的意思是說「在 proc 內,宣告一個 employeeName 區域變數,而這個 emplyeeName 變數,其實是呼叫者那一層某個變數的分身」,可是到底 employeeName 是誰的分身呢?答案就存在 varName 變數裏,經由呼叫 printName 時傳遞過來的,也就是特別標示的那行:
printName name
name (Golobal Scope 的一個變數)會傳入 printName 並儲存在 varName 變數中。所以 $varName 就會得到 name,那 upvar 指令就可以為 Global Scope 的這個 name 變數做出一個分身,就管它叫 employeeName 囉!
相同的事不需要 upvar 也做得到,為什麼要用 upvar 呢?是這樣的,因為我們沒辦法以 pass by value 的方式傳遞 array,如果要把陣列傳給 proc 處理, 就會需要用到 upvar 指令。底下是傳遞 array 到 proc 的範例:
# 用來設定陣列的內容
proc setEmployee {varName name age height weight} {
upvar $varName employee
set employee(name) $name
set employee(age) $age
set employee(height) $height
set employee(weight) $weight
}
# 用來印出陣列的內容
proc printEmployee {varName} {
upvar $varName employee
puts "Employee info:"
puts "Name = $employee(name)"
puts "Age = $employee(age)"
puts "Height = $employee(height)"
puts "Weight = $employee(weight)"
}
# 陣列一開始是空的
array set anEmployee {}
# pass by name (anEmployee array)
setEmployee anEmployee coopermaa 28 167 65
printEmployee anEmployee這段 Script 的輸出為:
Employee info:
Name = coopermaa
Age = 28
Height = 167
Weight = 65
upvar, pass by name
最新推荐文章于 2024-03-09 23:54:23 发布