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相关推荐

  1. pass基础架构分析

    pass基础架构分析 Relay 和 TVM IR,包含一系列优化passes,可提高模型的性能指标,如平均推理,内存占用,或特定设备的功耗.有一套标准优化,及特定机器学习的优化,包括常量折叠,死代码 ...

  2. 将编译器pass添加到Relay

    将编译器pass添加到Relay 编译器pass是扩展Relay功能集和对Relay程序执行优化的主要接口.通过编写编译器pass,可以修改AST或收集有关AST的信息,具体取决于目标.事实上,Rel ...

  3. AI中pass架构设计优化

    AI中pass架构设计优化 Relay 和 TVM IR,包含一系列优化passes,可提高模型的性能指标,例如平均推理,内存占用,或特定设备的功耗.有一套标准优化,及特定机器学习的优化,包括常量折叠 ...

  4. TVM,Relay,Pass

    TVM,Relay,Pass Relay介绍 主要结合TVM的文档(https://tvm.apache.org/docs/dev/relay_intro.html),介绍一下NNVM的第二代Rela ...

  5. Pass算子python 函数

    Pass算子python 函数 函数 • 函数是代码的一种组织形式 • 函数应该能完成一项特定的工作,而且一般一个函数只完成一项工作 • 有些语言,分函数和过程两个概念,通俗解释是,有返回结果的是函数 ...

  6. AI基础架构Pass Infrastructure

    AI基础架构Pass Infrastructure • Operation Pass o OperationPass : Op-Specific o OperationPass : Op-Agnost ...

  7. 如何使用TVM Pass Relay

    如何使用TVM Pass Relay 随着Relay / tir中优化遍数的增加,执行并手动维护其依赖关系变得很棘手.引入了一个基础结构来管理优化过程,将其应用于TVM堆栈中IR的不同层. Relay ...

  8. Pass Infrastructure基础架构(下)

    Pass Infrastructure基础架构(下) pass注册 PassRegistration该类在示例中简要显示了各种pass类型的定义 .该机制允许注册pass类,以便可以在文本pass管道 ...

  9. Pass Infrastructure基础架构(上)

    Pass Infrastructure基础架构(上) Operation Pass OperationPass Op-Specific OperationPass Op-Agnostic Depend ...

最新文章

  1. 我偷偷监听了他们的通信流量......
  2. mysql常见死锁_MySQL死锁系列-常见加锁场景分析
  3. Windows系统漏洞学习总结
  4. 单点登录之实战CAS5.1.x(六)——REST协议
  5. 写好的python如何在其它电脑上运行_如何在另一个文件中运行一个python文件?
  6. webservice的css哪里添加,jQuery_XML+XSLT+CSS+JQuery+WebService组建Asp.Net网(2), 3.       更 - phpStudy...
  7. PAT (Advanced Level) 1010 Radix(二分+模拟)
  8. RocketMQ源码解析-Consumer启动(1)
  9. 2017.9.6 外星人 思考记录
  10. 【转】 C#学习笔记14——Trace、Debug和TraceSource的使用以及日志设计
  11. NUC1657 All in All【字符串匹配】
  12. 中国联通创维SK-D740光猫管理员密码获取教程
  13. 使用VUE实现的数独游戏
  14. c语言 数据结构面试题及答案,数据结构c语言版试题大全(含答案).docx
  15. wpsjs插件开发-采用js和wps交互功能
  16. 【网页设计】HTML做一个属于我的音乐页面(纯html代码)
  17. typora脚注的快捷键
  18. 终于有人把数据挖掘讲明白了
  19. NOI / 1.2编程基础之变量定义、赋值及转换
  20. android 如何制作可编辑的表格,在手机wps中编辑表格的方法

热门文章

  1. 用递归方法将十进制转化为二进制数
  2. Java kafka监控 topic的数据量count情况,每个topic的Summed Recent Offsets(总结最近的偏移量)
  3. Ironic注册/部署/inspect/clean节点操作记录
  4. python基础学习task09
  5. HDU 6082 度度熊与邪恶大魔王 (完全背包)
  6. 11、Microsoft Visual Studio 2022 Installer Projects踩坑一
  7. Rasa课程、Rasa培训、Rasa面试、Rasa实战系列之RegexFeaturizer
  8. Windows环境下filebeat配置发送日志至Elasticsearch
  9. iOS———如何申请苹果公司开发者账号流程详细图文介绍(含邓白氏编码的申请方法详细介绍)
  10. 正交矩阵的定义及证明和性质