
这是编程语言普遍具有的控制特性,在介绍之前,让我先介绍一下Tcl/Tk里的布尔值。
布尔值是编程语言中,普遍存在的一种数据类型。即便没有这种数据类型,也会有这个概念,比如Tcl/Tk。
布尔值表示 "是、非" 或者 "真、假" 这么一个成对的概念。Tcl语言里都是字符串,它通过一些特定字符表示布尔值。首先,很好理解的表示布尔值的单词(大小写均可):
yes, no
true, false
on, off
其次,数值 1, 0
string is boolean "on"
#>> 1
但是实际上tcl语言中还有很多情况表示布尔值:
# 请看下例,做条件判断时,0以外的数值都被认为“真”,负值也是“真”,只有0代表“假”
if 0.1 {puts "yes"}
#>> yes
# 但是注意,单纯判断字符串时,1和0以外的数字不是布尔值
string is boolean 0.1
#>> 0
此外,布尔值单词的一部分,也被认为是布尔值(😱这是极其坑爹的设定)
# 以下都代表"真"
string is boolean "t"
string is boolean "tr"
string is boolean "tru"
string is boolean "ye"
# 对应的:f, fa, fal, fals, n 都代表"假"
# 注意:字母 o 不会被认为是布尔值,因为on和off开头都是o
string is boolean o
>> 0
# 但是of可以用来表示"假",因为它是off的一部分

如果 {表达式结果为"真"} 那么 {搞点事情~}
基本用法:if {表达式} then {代码段}
if命令用于条件执行。它需要两个必要参数:一个参数是表达式,另一个是代码段,而then参数是可选的。当表达式运算结果为真时就会执行代码段。
表达式可以是多行语句,结果必须是布尔值。并不局限于数学表达式,其具体可执行的范围,跟expr命令一样,可以参考expr命令的文档。then这个参数是可以省略的,主要用于加强代码的可读性。
if {2 > 1} {puts "2333"}
>> 2333
set vb 3
if {
$vb == 1
|| $vb == 2
|| $vb == 3
} then {
puts "行数比较多时,then参数可以提升代码可读性——Bilibili 象喻"
}
else参数:如果表达式结果为“假”时,就运行一段代码。
if {表达式} ?then? {代码段} else {代码段2}
如果 {表达式结果为"真"} 那么 {搞点事情~} 否则 {另外搞点事情~}
set vb 233
if {$vb == 1} {
puts "vb is one"
} else {
puts "vb is not one"
}
#>> vb is not one
elseif类似于在else后面再接一个if命令。一个if命令可以有多个elseif。
如果 {表达式结果为"真"} {搞点😼事情}
要不换个姿势 {表达式2结果为"真"} {搞点*事情}
再试一次 {表达式3结果为"真"} {搞点🦊事情}
实在不行 {搞点🐼事情}
set vbl 3
if {$vbl == 1} {
puts "vbl is 1"
} elseif {$vbl == 2} {
puts "vbl is 2"
} elseif {$vbl == 3} {
puts "vbl is 3"
} else {
puts "space.bilibili.com/494695230"
}
#>> vbl is 3
*注意,虽然看上去像语法,但是if命令就是普通的Tcl命令,它有接受多个参数,其中像then、else和elseif这样的参数属于预设参数,后接的代码段,无论多长本身也是参数。
switch命令用于进行匹配操作,该命令需要指定一个字符串来跟多个值进行匹配,每个进行匹配的值都有一段对应的代码段,当字符串与匹配值相同时,就执行这个匹配值对应的代码段。
*提示:Tcl语言的字符串只要不是{}括起来的,都能进行变量替换和命令替换。
该命令用于简化需要使用多个 if...elseif 语句的情况,也就是说如果不怕麻烦的话,该命令也可以用if...elseif语句来改写。
set x 3
switch $x {
1 {puts 1}
2 {puts 2}
default {puts "other"}
}
#>> other 可选参数
-exact 严格模式(默认值,精确识别特殊字符,比如: *、$ ) -glob 与 string match 命令相同,支持 * ? 匹配 -regexp 正则表达式 -nocase 不区分大小写 -- 表示参数结束(用于匹配字符串以 - 开头时,这会导致tcl误认为是参数-xxx)
foreach 变量名 列表 ?变量名2? ?列表2? {代码段}
用于遍历列表中的所有元素:
按顺序将元素赋值给变量,并执行代码段
完毕后,将下一个元素赋值给变量,再次执行代码段……
不断重复直到遍历全部元素
*提示:如果元素不足时,用空字符代替
# 简单例子:依次显示 1、2、3
foreach x {1 2 3} {
puts $x
}
# 双列表:先将1给x,a给y,运行代码;再将2给x,b给y;最后将3给x,y被指派空字符
foreach x {1 2 3} y {a b} {
puts "$x : $y"
}
#>>1 : a
#>>2 : b
#>>3 :
# 双变量的例子,本例中指定了两个变量:x和y
foreach {x y} {1 2 3 4 5} {
puts "$x : $y"
}
#>>1 : 2
#>>3 : 4
#>>5 :
# 第一轮:将1赋值给x;将2赋值给y
# 第二轮:依序,将3赋值给x;将4赋值给y
# 第三轮:继续,将5赋值给x;此时列中没有其它元素了,y为空字符
break中止当前的遍历/循环,直接结束遍历/循环命令。也有叫它“跳出”的。
# 本例中,如果元素值为2,则中止foreach命令
foreach x {1 2 3 4} {
puts $x
if {$x == 2} {break}
puts "----"
}
#>>1
#>>----
#>>2
# break命令直接中止当前遍历/循环,所以在break语句后面的代码不会执行
continue 跳过本轮遍历/循环,直接进入下一轮
# 本例中,如果元素值为2,则跳过本轮,接着进行下一轮
foreach x {1 2 3 4} {
if {$x == 2} {continue}
puts $x
}
#>>1
#>>3
#>>4
# continue不会中止整个遍历/循环,只会跳过本轮,直接进行下一轮
# 与break命令类似,continue命令也需要留意前后代码的顺序
# 一轮中:在continue前面的代码仍然会执行,只有后面的代码会被跳过
incr 给变量增加数值,主要搭配下面介绍的循环命令。
incr 变量名 ?增量? (变量值和增量都必须为整数)
set x 1
incr x
puts $x
#>> 2
incr x 231
puts $x
#>> 233
# 变量不存在时,incr命令会自动创建变量
incr y 666
puts $y
#>> 666
for 起始定义 测试条件 每轮最后执行的语句 {代码段}
For命令,也就是for循环,是编程语言里的经典循环语句,各个编程语言的具体实现略有不同,但是功能都类似。
TCL语言的for命令需要四个参数:第一个参数起始定义,第二测试条件,第三个参数是每轮最后执行的语句,最后一个参数是{代码段}。
for命令的运行方式:
首先只运行一次<起始定义>部分的语句
然后进入循环,判断<测试条件>的执行结果是否为真,如果结果为真,就运行{代码段}中的代码,代码段运行完毕之后,再运行<每轮最后执行的语句>,运行完毕之后,本轮结束,进入下一轮
下一轮继续判断<测试条件>的执行结果是否为真,如果为真,就继续执行{代码段}和<每轮最后执行的语句>,然后继续进入下一轮
一直循环直到<测试条件>为假,结束命令。
# 先定义x变量,进入循环。每轮末尾给x变量值加1,当x不小于3时,跳出循环
for {set x 1} {$x &lt; 3} {incr x} {
puts $x
}
#&gt;&gt; 1
#&gt;&gt; 2
# Tcl语言中x变量在循环结束后会保留,其它语言大都会删除该变量
puts $x
#&gt;&gt; 3
for {set x 1} {$x &lt; 5} {incr x} {
puts $x
set x 5
}
#&gt;&gt; 1
puts $x
#&gt;&gt; 6
while 测试条件 {代码段}
只要测试条件为"真",就会反复执行代码段
set x 1
while {$x&lt;3} {
puts &quot;x is $x&quot;
incr x
}
#&gt;&gt; x is 1
#&gt;&gt; x is 2
puts $x
&gt;&gt; 3
# while命令在使用时要保证能够跳出循环,否则会陷入无限循环:
while 1 {
puts &quot;无限循环&quot;
}