我读过,braace {}
中的所有内容都是文字(Tcl 中的反斜杠换行符除外。
所以,这是预期的:
% puts {\{}
\{
但是,我没有正确理解以下内容:
% puts { {}
<waits for close brace>
我希望它打印 {
,因为它在大括号内,应该按字面意思理解。我期望的是:一旦遇到左括号,就按字面意思理解所有内容,直到遇到第一个右括号。但这似乎并没有发生。请消除我的误解。
最佳答案
对于 Tcl
程序员来说,大括号始终是乞讨时的噩梦。
如您所知,大括号的主要经验法则如下,
规则 1:大括号内不发生替换
除了上述规则,我们在 Tcl
中还有一些其他规则。
大括号最重要的用途之一是延迟求值
。
规则 2:延迟评估
这意味着 Tcl
解析器不会立即处理特殊字符。
相反,它们将作为参数的一部分传递给命令过程,命令过程将自行处理特殊字符。将脚本传递给 Tcl
命令时几乎总是使用大括号,如以下计算 5 的阶乘的示例所示:
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 中所述,在代码 puts {\{}
中,移除外括号后,我们只有 \{
。这将传递给 puts
命令。现在,根据规则 5,在 \{
中,当 Tcl
遇到反斜杠左大括号时,它不会尝试匹配右大括号。此外,解析时不会删除该反斜杠。这就是 \{
在控制台中打印的原因。
在 puts {{}
的情况下,Tcl 解释器显然会等待右大括号,因为它是不平衡的。
注意:所有地方都会有异常(exception)。好吧,Tcl
在大括号方面也有相同之处。我们开始说大括号内没有替换。但是,出现在大括号之间的唯一替换形式是反斜杠换行符。
在Tcl
中,反斜杠
也用于续行。
if 1 {
puts "Brace Yourself!!!"
}
你可以将上面的重写为
if 1 \
{
puts "Brace Yourself!!!"
}
同样,使用反斜杠换行符,替换将发生如下所示。
puts {Thanks to\
Stackoverflow}
代码的输出将显示在一行中。
关于Tcl 大括号引用 : is everything literal inside braces?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28133138/