过程与作用域

news/发布时间2024/5/17 11:48:39

一个过程创建好后,就可以象 Tcl 内建命令一样直接使用。 

Tcl8.0 以后的版本增加了名字空间(name space),它为过程和变量提供了新的作用域。 

1. proc—过程定义命令 

使用 proc 命令定义过程: 

proc procName { var1 var2 ... } { body

 

} 

proc 命令有三个参数:

  • procName 是定义的过程名字

  • {var1 var2 ...}是输入、输出参数列表;

  • body 是过程执行命令体。 body 的界定大括弧和 if 等命令的命令执行体遵循相同的规则和注意事项 

  • 可以使用 return 命令在需要的时候返回调用程序。 
  • 使用过程的时候,不一定输入所有的参数值。过程的输入参数可以有默认值。默认值由{默认参数名 默认值}指定。如果调用过程时没有指定这些参数的值则会使用其默认值,否则使用输入值来替代默认值。在使用默认参数的时候要注意,如果默认参数之后还有非默认参数,则在调用此过程的时候,默认参数的值也要求输入,否则会出错。

带有默认参数的过程定义示例:

proc Test {a {b 7} {str "hello World"}}  {

  puts "$str"

  return [expr $a * $b]

}

Test 10

 => Hello World

  70

Test 10 5 "Call Test"

 => Call Test

  50

如果参数列表中最后一个参数是 args 的话,则过程可以接收可变数目的输入参数。当调用过程时,除了指定参数以外的参数值都被 args 接收。如果参数列表中只有 args 一项,则 args 接收所有输入参数值

proc vParam {args} {

  puts "input values are : $args"

vParam

 => input values are :

vParam 1 "Hello" 2 3 "End"

 => input values are : 1 Hello 2 3 End

2. 作用域       

2.1 过程的作用域           

默认情况下,过程名具有单一的作用域即全局作用域。所以可以在脚本的任何地方使用一个过程(使用之前,过程必须已经定义)。可以通过名字空间来限定过程的作用范围。如可以通过名字空间命令设置一个过程可以让外部调用,也可以设置过程不为外部所使用。 

过程的定义可以嵌套,低层定义的过程只有在上层过程被执行后才能生效。 

proc one {} {

  puts "I'm one"

  proc two {} {

     puts "I'm two"

  }

  puts "Call two in one:"

  two

}   

two

 => invalid command name "two"

one

 => I'm one

  Call two in one:

  I'm two

  two

 => I'm two

2.2 变量的作用域 

对于变量而言,根据其作用域可分为全局变量和局部变量。在所有过程之外定义的变量为外部变量,即全局变量,它的作用域为从开始定义到执行结束,除非中间有显式取消其定义在一个过程体内定义的变量为内部变量,即局部变量,局部变量的作用域只限于过程内部使用,在此过程外面不能使用这些变量。在一个过程内部,即可以使用自身的局部变量,又可以使用全局变量,但是全局变量在过程内部不会自动可见,需要通过 global 命令来事先声明。因为作用域不同,所以过程中的变量可以与全局变量、其他过程中的变量有相同的名字。

在过程定义中的输入、输出参数列表中的参数为过程的内部参数。 

set a 5

set b -8

set c 10

proc P1 {a} {

set b 42

global c

puts "$a"

puts "$b"

puts "$c"

}

P1 $b

 => -8

  42

  10

全局变量的定义不一定要在过程外完成,可以在任何一个过程中完成,其效果是将一个局部变量的作用域进行了扩展但是在引用全局参数的值之前全局参数应首先已被赋值

另外当一个过程中要使用与局部变量相同名字的参数时,用global 命令就要小心:你不能在定义完成一个局部变量后再用 global 命令使用同名的全局参数,这会出错 

proc P2 {} {

  global var1

  set var1 100

  puts "var1=$var1"  #在P2内定义全局变量

}

proc P3 {} {

  global var1

  puts "var1=$var1"

}

proc P4 {} {

  global var2

  put $var2

}

proc P5 {} {

  set a 30

  global a

  puts "a=$a"

}

P2

 => var1=100

P3

 => var1 = 100

P4  #试图使用不存在的全局变量

 => can't read "var2:no such variable"

P5  #在定义局部变量后视图引用同名全局变量

 => variable "a" already exists

还有另外一种方式来直接使用全局变量即用双冒号( ::,见下例:

proc test {} {

  puts "The value of global variable var1 is $::var1"

}

set var1 20

 => 20

test

 => The value of global variable var1 is 20

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ulsteruni.cn/article/52664314.html

如若内容造成侵权/违法违规/事实不符,请联系编程大学网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

进阶数据结构

学到哪写到哪说是 既然打ACM可以用板子,我就不用再隔几天敲一遍板子了 只能说赢麻了 线段树 线段树是一种利用二分思想的数据结构,主要用于区间修改以及查询问题。 它的基本思想是可以用一下一个图来表示,其中最底层的是原数组简单来说,对于每个区间的修改或者查询操作,我…

echarts 两个曲线之间填充并且不遮挡的办法

echarts 两个曲线之间填充 可以用两条曲线 ,第一条填充白色 ,然后 第2条填充想要的颜色 ,如下面的代码 option = {title: {text: 堆叠区域图},tooltip : {trigger: axis},legend: {data:[最小值,最大值]},toolbox: {feature: {saveAsImage: {}}},grid: {left: 3%,right: 4%,…

球体与正方体[正六面体]

主要整理球体与正方体[正六面体]的切接问题前言 常用结论:给定一个棱长为 \(a\) 的正方体[即正六面体],则其面对角线长为\(\sqrt{2}a\),其体对角线长为\(\sqrt{3}a\);且正六面体棱长、面对角线、体对角线三者之比为\(1\)\(\;:\;\)\(\sqrt{2}\)\(\;:\;\)\(\sqrt{3}\);设正方…

Python 物联网入门指南(八)

原文:zh.annas-archive.org/md5/4fe4273add75ed738e70f3d05e428b06 译者:飞龙 协议:CC BY-NC-SA 4.0第三十章:制作机械臂 最后,我们终于到达了大多数人自本书开始以来就想要到达的地方。制作一个机械臂!在本章中,我们将学习机械臂工作背后的概念。毫无疑问,我们也将制作…

甘特图使用小诀窍,项目把控游刃有余

在项目管理过程中,掌握甘特图的使用技巧可以让你事半功倍,高效规划和监控项目进度。作为一种视觉化的工具,甘特图直观地展示了任务的开始和结束时间、持续时间以及任务之间的依赖关系,有助于预测和优化资源分配。掌握以下几个小诀窍,你就能驾驭甘特图,游刃有余地把控整个项目。…

实验一 二手交易平台APP原型设计

一、实验题目:原型设计 二、实验目的:掌握产品原型设计方法和相应工具使用。 三、实验要求 1.对比分析墨刀、Axure、Mockplus等原型设计工具的各自的适用领域及优缺点(至少3条)。 墨刀的适用领域及优缺点 适用领域 墨刀是一款在线原型设计与协同工具,借助墨刀,产品经理、…