大括号{}
, 和圆括号 ,在 Tcl()
中不可互换。
形式上,大括号(除了一个例外)是一种引用,表示不再对内容执行替换。在上面的第一种情况下,这意味着该参数被传递给if
而没有替换,它将它作为一个表达式来计算。表达式子语言具有与一般 Tcl 高度相似的大括号解释方案;它们表示一个文字值,无需对其执行进一步的替换。
相比之下,括号在 Tcl 中大多不是特殊的。例外情况是数组元素的名称(例如$foo(bar)
,其他一些东西)。在 Tcl 中使用括号(无论是否平衡)作为命令名的一部分是完全合法的,但你可能会让你的程序员同事抱怨你写了令人困惑的代码。
细节
在这种特定情况下, this 的测试表达式if
:
if {{$number == 1 && $name == "hello"} || {$number == 0&&$name == "yes"}} {...}
被解析为:
废话#1 LOGICAL_OR 废话#2
其中每个blah
都是文字。不幸的是,blah#1
(完全等于$number == 1 && $name == "hello"
)没有布尔解释。(也没有,blah#2
但我们从不考虑这一点。)这里的事情肯定是非常错误的!
最简单的解决方法是将那些虚假的大括号改回括号:
if {($number == 1 && $name == "hello") || ($number == 0&&$name == "yes")} {...}
我敢打赌这就是你最初想要的。
警告:高级主题
但是,另一个解决方法是添加一些额外的内容:
if {[expr {$number == 1 && $name == "hello"}] || [expr {$number == 0&&$name == "yes"}]} {...}
这通常不是一个好主意——额外的体积没有额外的收益——但在你试图使用动态生成的表达式作为测试条件的地方是有意义的。除非你真的很确定你需要这样做,否则不要这样做!我是认真的。这是一种非常先进的技术,您几乎不需要,而且通常有更好的方法来实现您的总体目标。如果您认为您可能需要它,看在上帝的份上,请在 SO 上提问,我们将尝试找到更好的方法;几乎总是有一个可用的。