【语法|变量】
l 脚本、命令和单词
Tcl提供了大约100条命令,Tk提供了另外几十条,脚本包含一条或多条,通过换行符或分号分隔开.
set a 12
set b 23
每个命令由多个单词组成,以空格来分隔,首字母为命令名,所以:
1. set -> 单词,同时也是命令名
2. a -> 单词
3. 12 -> 单词,将该值赋予a
l 处理命令
Tcl处理命令分两步: 解析和执行
1) 在解析阶段,Tcl进行一系列简单字符串操作,比如将$input变量中存放的input字符串来代替
2) 在执行阶段,命令中的各个单词有了具体含义。Tcl把第一个单词作为命令名称,并根据传递过来的参数,执行该命令。
图示如下:
l 替换
方式一:变量替换
例1: 计算或赋值
例2: 创建4个按钮事件 分别为 .b1,.b2, .b3, .b4
% foreach num {1 2 3 4} { button.b$num }
备注:
替换不影响命令中每个单词的分割,即使替换后的字符包括空格,制表符,换行符,等空白字符,也不影响。
方式二: 命令替换
备注:
命令替换是把一个单词的部分或全部替换为一个命令的结果,通过[]来进行,会调用[]中的命令,比如上面的expr命令.
方式三: 反斜杠替换
用于向单词中插入像\n、[、$、空格符这样会被Tcl解析器认为有特殊含义的字符,如下所示:
备注:
反斜杠替换和一般的替换不同,这种替换在Tcl解释器解释命令前就要单独进行,这意味着用于替换空格符会被作为单词分隔符看待,除非它们被””或{}括起来.
l 双引号引用
Tcl中提供了一些方法,可以阻止解析器对$和分号等字符进行处理,这些方法称为引用。
例1: 要将hello world赋给msg,不用双引号的话会报错.
这个时候就需要引用:
例2: 将空格、制表符、换行以及分号做普通字符处理.
例3: 将msg设置为包含一个变量名,该变量平方等信息的字符串
l 大括号引用
如果说双引号对\n还会做特殊处理的话,那么大括号则是更彻底的引用形式,它会取消其中所有特殊字符的特殊意义。所有的空格,制表符,换行符以及分号都会作为普通字符处理。
例1: 将上面msg信息如实打印出来
l 参数展开
Tcl会将一个列表作为参数传递给一个过程。先看一个例子:
例1: 要将d:\test目录下,所有.h结尾的文件删除.
像上面是删除不掉的,为什么呢?因为glob命令返回的是一符合*.h形式的文件列表,例如a.h, b.h, c.h, d.h,整个文件列表作为一个参数传递给file delete命令,会因为找不到a.h, b.h,c.h,d.h而删除失败.那么要如何删掉呢?
方式一: 开头加个{*}
方式二: 文件名全部列出
方式三: 借助eval命令解析,让其重新传给filedelete
l 注释
如果一条命令的第一个非空白字符是#,那么这一行将被视为注释。注意:注释符必须出现在Tcl预期将获得命令的第一个字符位置上。如果注释出现在其他地方,会被看作一个普通字符,看成一个命令单词的一部分。
第二行#出现在一条命令中间,导致该set命令接收到3个参数,所以错误。最后一个#被视为注释符是因为它紧接在标志一条命令终止的;后面。要准确理解上面标红的意思,再看下面两个例子。
例1: {}中非注释的情况
{}中的所有字符被视为一个参数,作为字符串赋给set指定的变量,所以不是注释!
例2: {}中注释的情况
这里面有两个{},if命令会把第一个{}视为boolean型表达式处理,如果为真的话,它会调用Tcl解释器将第二个参数作为Tcl脚本处理。在Tcl解析器再次进行解析时,以#开头的第一行才被识别为注释。
例3: 出现在注释中的大括号常导致错误
另外一种用途,用if命令来将多行注释。看下面例子.
在Java中可以用
/*
*/
在Python中用三个单引号对,或三个双引号对来多行注释。
Tcl中可以用if 命令来达到同样的效果: 多行注释的问题。
If 0,即条件为假,下面的分支就不走了,从而达到注释的目的。
l errorInfo
异常返回的时候,错误信息会保存在全局变量errorInfo中,
出现错误后,Tcl会把errorInfo设置为一个栈,保存产生错误的确切位置,可以用puts $errorInfo输出这个变量的值。
l set命令
该命令可以用来创建、读取和修改,第一个参数是变量名,第二个参数如果有话,是变量的新值.
l append命令
该命令用于在字符串的末尾添加一个字符,特点:因这是Tcl的内部表达式,处理起来速度快!
l 数组
数组是元素的集合,每一个元素有自己的名字和值的变量。包括两部分:数组名+数组中的元素名.下面是常见的两种数组定义方式:
方式一:set arrayName(element)方式
方式二: array set arrayName{} 方式
备注:
1. 在Tcl中数组是无序的数据结构(以哈希表的方式存储),而列表才是有序的排列.
2. 如果数组的元素包含空格,则需要用\转译,或变量替换
l 数组的相关命令
命令一: array names arrayName:返回指定数组的元素列表
命令二: array size arrayName: 数组中定义了多少个元素
命令三: array exists arrayName: 用于检验某个数组是否存在.
命令四: array set和array get: 后者是获取数组的字典
数组遍历: 一般用foreach来遍历数组,例如:
l incr命令
该命令提供了改变变量值的简单方法.incr读入两个参数,分别是变量名和一个整数
8.5之前对不存在的变量,比如说上面的变量y,会报错!但在8.5及之后的版本,会创建该变量,默认+1.
l unset命令和array unset
unset命令用于销毁变量。可以接收多个变量,每个参数为变量名,也即意味着,一次可以删除多个变量,比如说:
array unset用于销毁数组:
l 预定义变量
Tcl库自动创建和管理了一些全局变量。最常用的部分如下:
1. argv0, argc, argv
2. env
3. tcl_platform
l 其他变量功能
tace命令: 用于监视变量,在变量设置、被读取、或被删除时调用指定的Tcl脚本。Trace命令在调试时很有用,该变量还允许创建只读变量,可以把变量跟踪用于“传播”,例如:只要变量值发生变化,数据库或屏幕上显示的值就即时更新。
global和upvar命令:可由过程使用,访问不由它所有的局部变量。
namespace命令:创建并管理命名空间,命名空间是命令和变量的命名集合。命名空间可以将命令和变量分隔开来,确保他们不会干扰其他命名空间中的命令和变量。