TCL中的if语句 [英] the if statement in TCL

查看:23
本文介绍了TCL中的if语句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对以下代码的 tcl 中的 if 语句有疑问:

I have a question about if statement in tcl of the following code:

if {(($number == 1)&&($name == "hello")) || (($number == 0)&&($name == "yes"))} {
    #do something here
}

上面的代码有效,但如果我这样写:

The above code works, but if I wrote it down like this:

if {{$number == 1 && $name == "hello"} || {$number == 0&&$name == "yes"}} {
    #do something here
}

它抱怨 $number 应该是一个布尔值,为什么?第二个不是有效的表达式吗?如何纠正?

It complains that the $number is expected to be a boolean, why? Is the second one not a valid expression? How to correct it?

推荐答案

大括号 {} 和括号 ()不是 在 Tcl 中可互换.

Braces, {}, and parentheses, (), are not interchangeable in Tcl.

从形式上讲,大括号是(一个例外)一种引用,表示没有进一步的替换对内容进行.在上面的第一种情况下,这意味着该参数被传递给 if 而不进行替换,这将其计算为表达式.表达式子语言具有与一般 Tcl 强相似的大括号解释方案;它们表示没有进一步替换的文字值.

Formally, braces are (with one exception) a kind of quoting that indicates that no further substitutions are to be performed on the contents. In the first case above, this means that that argument is delivered to if without substitution, which evaluates it as an expression. The expression sub-language has a strongly-analogous brace interpretation scheme to general Tcl; they denote a literal value with no further substitutions to perform on it.

相比之下,括号在 Tcl 中大多并不特殊.例外情况是数组元素的名称(例如,$foo(bar))、表达式子语言(使用它们进行分组,就像编程中的数学表达式一样)和正则表达式子语言(它们是不同类型的分组和其他一些东西).在 Tcl 中将括号(无论是平衡的还是其他形式的)用作命令名称的一部分是完全合法的,但是您可能会因为编写令人困惑的代码而遭到其他程序员的抱怨.

By contrast, parentheses are mostly not special in Tcl. The exceptions are in the names of elements of arrays (e.g., $foo(bar)), in the expression sublanguage (which uses them for grouping, as in mathematical expressions all over programming) and in the regular expression sublanguage (where they are a different type of grouping and a few other things). It is entirely legal to use parentheses — balanced or otherwise — as part of a command name in Tcl, but you might have your fellow programmers complaining at you anyway for writing confusing code.

在这个特定情况下,这个if的测试表达式:

In this specific case, the test expression of this if:

if {{$number == 1 && $name == "hello"} || {$number == 0&&$name == "yes"}} {...}

被解析为:

blah#1 LOGICAL_OR blah#2

其中每个 blah 都是一个文字.不幸的是,blah#1(完全等于 $number == 1 && $name == "hello")没有布尔解释.(blah#2 也没有,但我们从不费心去考虑.)这里的事情肯定会出错!

where each blah is a literal. Unfortunately, blah#1 (which is exactly equal to $number == 1 && $name == "hello") has no boolean interpretation. (Nor does blah#2 but we never bother to consider that.) Things are definitely going very wrong here!

最简单的解决方法是将那些假大括号改回括号:

The simplest fix is to change those bogus braces back to parentheses:

if {($number == 1 && $name == "hello") || ($number == 0&&$name == "yes")} {...}

我敢打赌这就是你最初想要的.

I bet this is what you originally wanted.

然而,另一个解决方法是添加一些额外的内容:

However, the other fix is to add in a little extra:

if {[expr {$number == 1 && $name == "hello"}] || [expr {$number == 0&&$name == "yes"}]} {...}

这通常不是一个好主意 - 没有额外收益的额外批量 - 但是当您尝试使用动态生成的表达式作为测试条件时它是有意义的.不要这样做,除非你真的很确定你需要这样做!我是认真的.这是一种您几乎不需要的非常先进的技术,而且通常有更好的方法来实现您的总体目标.如果您认为您可能需要它,看在上帝的份上,请在 SO 上询问,我们将尝试找到更好的方法;几乎总有一款可用.

This is normally not a good idea — extra bulk for no extra gain — but it makes sense where you're trying to use a dynamically-generated expression as a test condition. Do not do this unless you're really really certain you need to do this! I mean it. It's a very advanced technique that you hardly ever need, and there's often a better way to do your overall goal. If you think you might need it, for goodness' sake ask here on SO and we'll try to find a better way; there's almost always one available.

这篇关于TCL中的if语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆