我已经读过,braace {}
中的所有内容都是字面的(除了Tcl中的反斜杠换行符)。
所以,这是预期的:
% puts {\{}
\{
但是,我不能正确理解以下内容:
% puts { {}
<waits for close brace>
我希望它打印{
,因为它在括号内,应该按字面意思。我期待的是:一旦你遇到一个开放的支撑,直到你遇到第一个闭合支撑,直到你。但这似乎并没有发生。请清除我的误解。
答案 0 :(得分:3)
支持Tcl
程序员时,大括号总是一场噩梦。
如您所知,带括号的主要拇指规则如下,
规则1:大括号内没有替换
除上述规则外,Tcl
还有更多内容。
大括号最重要的用途之一是defer evaluation
。
规则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命令时一次性完成。
规则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
请求的命令替换,但仅限于{{ 1}}计算它的第二个参数来执行循环。
规则5:如果支撑被反斜杠,那么它不会计入结束括号中的单词的匹配括号。解析单词时不会删除反斜杠。
如规则4中所述,在代码while
中,删除外括号后,我们只有puts {\{}
。这将传递给\{
命令。现在,根据规则5,在puts
中,当\{
遇到后退的开放式大括号时,它不会尝试匹配近距离大括号。此外,解析时不会删除反斜杠。这就是Tcl
在控制台中打印的原因。
对于\{
,Tcl解释器显然会等待紧密括号,因为它是不平衡的。
注意:所有地方都会有例外。那么,puts {{}
在括号方面也是一样的。我们开始说在括号内没有替换。但是,大括号之间唯一的替换形式是反斜杠换行符。
在Tcl
中,Tcl
也用于续行。
backslash
您可以将上述内容重写为
if 1 {
puts "Brace Yourself!!!"
}
同样地,使用反斜杠换行符,将发生替换,如下所示。
if 1 \
{
puts "Brace Yourself!!!"
}
代码的输出将在一行中看到。
答案 1 :(得分:2)
括号中的括号嵌套(除非引用),因为这是规则(Dodekalogue中的[6])。这个规则的原因是,支撑词的内容通常是带有几个开括号和闭括号的结构化表达式,很可能甚至是几个开启和关闭括号的级别。当不使用它们来构造表达式时,让解析器抱怨不平衡的大括号的好处超过了引用大括号的麻烦。