Tcl大括号引用:大括号内的所有内容都是文字吗?
我已经读到,braaceTcl大括号引用:大括号内的所有内容都是文字吗?,tcl,interpreter,curly-braces,Tcl,Interpreter,Curly Braces,我已经读到,braace{}中的所有内容都是文字(除了Tcl中的反斜杠换行符)。 因此,这是预期的: % puts {\{} \{ 但是,我不完全理解以下内容: % puts { {} <waits for close brace> %put{{} 我希望它能打印{,因为它在大括号内,应该按字面理解。我期望的是:一旦你遇到一个打开的大括号,就按字面理解一切,直到你遇到第一个关闭的大括号。但这似乎没有发生。请澄清我的误解。大括号总是乞求Tcl程序员的噩梦 如你所知,带大括号的主
{}
中的所有内容都是文字(除了Tcl中的反斜杠换行符)。
因此,这是预期的:
% puts {\{}
\{
但是,我不完全理解以下内容:
% puts { {}
<waits for close brace>
%put{{}
我希望它能打印
{
,因为它在大括号内,应该按字面理解。我期望的是:一旦你遇到一个打开的大括号,就按字面理解一切,直到你遇到第一个关闭的大括号。但这似乎没有发生。请澄清我的误解。大括号总是乞求Tcl
程序员的噩梦
如你所知,带大括号的主要拇指法则如下:
规则1:大括号内不发生替换
除了上述规则,我们在Tcl
中没有更多的规则
大括号最重要的用途之一是推迟求值
规则2:延期评估
这意味着Tcl
解析器不会立即处理特殊字符
相反,它们将作为其参数的一部分传递给命令过程,命令过程将处理特殊字符本身。在将脚本传递给Tcl
命令时,几乎总是使用大括号,如下例中计算五的阶乘:
set result 1
set i 5
while {$i > 0} {
set result [expr $result*$i]
set i [expr $i-1]
}
while
循环的主体用大括号括起来以推迟替换。while
在循环的每次迭代期间将脚本传递回Tcl
进行评估,此时将执行替换。在这种情况下,推迟替换非常重要,以便每次都重新执行替换while在解析while命令时对循环体求值,而不是一次性地求值
规则3:大括号嵌套。proc命令的最后一个字在第一行打开大括号后开始,包含最后一行关闭大括号之前的所有内容
规则4:Tcl解释器删除外部大括号,并将它们之间的所有内容(包括几个嵌套的大括号对)作为参数传递给proc
。
proc power {base p} {
set result 1
while {$p > 0} {
set result [expr $result*base]
set p [expr $p-1]
}
return $result
}
在上述情况下,proc
的第三个参数包含两对嵌套大括号(最外面的大括号由Tcl
解析器删除)。使用[expr$p-1]请求的命令替换当解析proc
命令时,甚至当解析while
命令作为执行过程主体的一部分时,也不会执行,但只有当while
计算其第二个参数以执行循环时,才会执行
规则5:如果大括号是反斜杠,则大括号中包含的单词的匹配右大括号结束时不算反斜杠。解析该单词时,反斜杠不会被删除。
正如规则4所解释的,在代码put{\{}
中,在移除外部大括号后,我们只有\{
一个。这将传递给put
命令。现在,根据规则5,在\{
,当Tcl
遇到反斜杠打开的大括号时,它不会尝试匹配关闭的大括号。此外,解析时该反斜杠也不会被删除。这就是为什么控制台中会打印\{
在放置{{}
的情况下,Tcl解释器显然会等待右大括号,因为它是不平衡的
注意:所有地方都会有例外。好吧,Tcl
在大括号内也有同样的情况。我们开始说大括号内没有替换。但是,大括号之间发生的唯一替换形式是反斜杠换行符。
在Tcl
中,反斜杠
也用于行继续
if 1 {
puts "Brace Yourself!!!"
}
您可以将上述内容重新编写为
if 1 \
{
puts "Brace Yourself!!!"
}
同样,使用反斜杠换行符时,将发生替换,如下所示
puts {Thanks to\
Stackoverflow}
代码的输出将显示在一行中
引用:大括号嵌套(除非被引用)在大括号单词中,因为这是Dodekalogue中的规则([6])。使用此规则的原因是,带大括号的单词的内容通常是一个包含多个开大括号和闭大括号的结构化表达式,甚至很可能是多个级别的开大括号和闭大括号。让解析器抱怨大括号不平衡的好处大于当您不使用大括号时必须引用大括号的麻烦构造表达式
您可以在Tcl命令中使用其他形式的引用。请再试一次;它很有效!proc addThings“a b”“return\[expr{\$a+\$b}\]
。不过不要再试一次;继续这样做会让人非常恼火…