15

次のコードの tcl の if ステートメントについて質問があります。

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

上記のコードは機能しますが、次のように書き留めると:

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

$numberがブール値であることが期待されていると不平を言っていますが、なぜですか? 2 番目の式は有効な式ではありませんか? それを修正する方法は?

4

4 に答える 4

36

中括弧{}、および括弧 、()はTcl では交換できません。

正式には、中括弧は ( 1 つの例外を除いて) 内容に対してそれ以上の置換が実行されないことを示す一種の引用です。上記の最初のケースでは、これはその引数が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に尋ねてください。私たちはより良い方法を見つけようとします; ほとんどの場合、利用可能なものがあります。

于 2012-06-29T12:55:53.360 に答える
1

つまりif、条件スクリプトに特別な「ミニ言語」を使用します。これは、exprコマンドで理解されるものと同じです。これはifマニュアルページに記載されています:

ifコマンドは、expr1を式として評価します(exprが引数を評価するのと同じ方法で)。

非常にLISPやUnixシェルに似ているTcl自体とは対照的に、その「exprミニ言語」は、Cのように感じるという意味ではるかに「伝統的」です。

于 2012-06-29T16:09:03.537 に答える
1

番号に($number == 1)1 が割り当てられ、比較が行われます。例:1==1ここでは、出力はブール値です。しかし、花のブラケットが比較{$number == 1 && $name == "hello"}されるため、 $number は割り当てられていないため、得られる出力はブール値ではありません。$number1

于 2014-12-11T06:54:44.707 に答える
1

あなたが得ているエラーメッセージは、それ$numberがブール値でなければならないという意味ではないと思います(私はメッセージを受け取りましたexpected boolean value but got "$number == 1 && $name == "hello"")。これは、文字列$number == 1 && $name == "hello"がブール値ではないことを意味します - これは間違いなく真実です。式で中括弧を使用すると、ifこれらの文字列は評価されず、文字列としてそのまま解釈されます。

于 2012-06-29T12:29:31.297 に答える