14 tcl
我对以下代码的tcl中的if语句有疑问:
if {(($number == 1)&&($name == "hello")) || (($number == 0)&&($name == "yes"))} {
#do something here
}
Run Code Online (Sandbox Code Playgroud)
上面的代码有效,但如果我这样写下来:
if {{$number == 1 && $name == "hello"} || {$number == 0&&$name == "yes"}} {
#do something here
}
Run Code Online (Sandbox Code Playgroud)
它抱怨说$number预计会是一个布尔值,为什么呢?第二个不是有效的表达吗?怎么纠正呢?
Don*_*ows 34
大括号{}和括号在Tcl ()中不可互换.
正式地,大括号(除了一个例外)是一种引用,表示不对内容执行进一步的替换.在上面的第一种情况中,这意味着该参数被传递给if没有替换,它将其作为表达式进行计算.表达式子语言对一般Tcl具有强烈类似的括号解释方案; 它们表示一个字面值,没有进一步的替换来执行它.
相比之下,括号在Tcl中大多不是特殊的.例外是在数组元素的名称中(例如,$foo(bar)),在表达式子语言中(使用它们进行分组,如在整个编程中的数学表达式中)和正则表达式子语言(其中它们是不同类型的分组和其他一些事情).使用括号 - 平衡或其他 - 作为Tcl中命令名称的一部分是完全合法的,但是你可能会让你的程序员抱怨你编写令人困惑的代码.
在这个特定的情况下,测试表达式如下if:
if {{$number == 1 && $name == "hello"} || {$number == 0&&$name == "yes"}} {...}
Run Code Online (Sandbox Code Playgroud)
被解析为:
blah#1 LOGICAL_OR blah#2
每个blah都是字面意思.不幸的是,blah#1(完全等于$number == 1 && $name == "hello")没有布尔解释.(也没有,blah#2但我们从不费心去考虑.)这里的事情肯定是非常错误的!
最简单的解决方法是将那些伪造的括号改回括号:
if {($number == 1 && $name == "hello") || ($number == 0&&$name == "yes")} {...}
Run Code Online (Sandbox Code Playgroud)
我打赌这是你原本想要的.
但是,另一个修复是添加一些额外的:
if {[expr {$number == 1 && $name == "hello"}] || [expr {$number == 0&&$name == "yes"}]} {...}
Run Code Online (Sandbox Code Playgroud)
这通常不是一个好主意 - 额外的批量没有额外的收益 - 但是在你尝试使用动态生成的表达式作为测试条件的情况下这是有意义的.不这样做,除非你真的确定你需要做到这一点!我是认真的.这是一项非常先进的技术,您几乎不需要,而且通常有更好的方法来实现您的总体目标.如果你认为你可能需要它,为了善良,请问这里SO,我们会试着找到一个更好的方法; 几乎总有一个可用.