upvar, pass by name
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的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MTK5G平台 MT6885/MT685
- 下一篇: 在.NET中使用正则表达式对太平洋产品参