26

変数がこれまたはあれと等しくないことを確認しようとしています。次のコードを使用してみましたが、どちらも機能しません。

if x ~=(0 or 1) then
    print( "X must be equal to 1 or 0" )
    return
end


if x ~= 0 or 1 then
    print( "X must be equal to 1 or 0" )
    return
end

これを行う方法はありますか?

4

3 に答える 3

59

orあなたの問題は、このようなプログラミング言語を学ぶ人々に共通する演算子の誤解から生じています。はい、差し迫った問題は と書くことで解決できますがx ~= 0 and x ~= 1、試みた解決策がうまくいかない理由についてもう少し詳しく説明します。

x ~=(0 or 1)または、「x is not equal to zero x ~= 0 or 1or one」という文のようにこれを解析するのが自然です。そのステートメントの通常の理解では、「x」は主語、「等しくない」は述語または動詞句、「0 または 1」は目的語であり、接続詞によって結合された一連の可能性です。セット内の各項目に動詞を使用して主語を適用します。

ただし、Lua はこれを英語の文法規則に基づいて解析するのではなく、操作の順序に基づいて 2 つの要素のバイナリ比較で解析します。各演算子には、評価される順序を決定 する優先順位があります。数学の加算が乗算よりも優先順位が低いのと同様に、 は よりも優先順位が低くなりますor~=すべては括弧よりも優先順位が低くなります。

その結果、 を評価するときx ~=(0 or 1)、インタープリターは最初に0 or 1(括弧があるため) を計算し、次にx ~=最初の計算の結果を計算します。2 番目の例ではx ~= 0、その計算の結果を計算してから に適用しますor 1

論理演算子orは、「この値が nil および false と異なる場合は最初の引数を返します。それ以外の場合は、2 番目の引数を返します」。関係演算子~=は等値演算子の逆です==。引数の型が異なる場合 (x数値ですよね?) は true を返し、それ以外の場合は通常どおり引数を比較します。

これらのルールを使用すると、(演算子を適用した後に)x ~=(0 or 1)に分解され、x が 1 を含む 0 以外の値である場合、これは「true」を返しますが、これは望ましくありません。もう 1 つの形式は、 最初に評価されます (x の値に応じて、true または false を返す場合があります)。次に、または のいずれか に分解されます。最初のケースではステートメントは を返し、2 番目のケースではステートメントは を返します。Lua の制御構造はandのみを false と見なし、それ以外はすべて true と見なすため、これは常にステートメントに入りますが、これも望ましくありません。x ~= 0orx ~= 0 or 1x ~= 0false or 1true or 11truenilfalseif

プログラミング言語で提供されているような二項演算子を使用して、単一の変数を値のリストと比較する方法はありません。代わりに、変数を各値と 1 つずつ比較する必要があります。これを行うにはいくつかの方法があります。最も簡単な方法は、De Morgan の法則を使用して、「1 か 0 でない」(2 項演算子では評価できない) ステートメントを「1 も 0 でもない」として表現することです。これは、2 項演算子で自明に記述できます。

if x ~= 1 and x ~= 0 then
    print( "X must be equal to 1 or 0" )
    return
end

または、ループを使用してこれらの値を確認できます。

local x_is_ok = false
for i = 0,1 do 
    if x == i then
        x_is_ok = true
    end
end
if not x_is_ok then
    print( "X must be equal to 1 or 0" )
    return
end

最後に、関係演算子を使用して範囲をチェックし、x が範囲内の整数であることをテストできます (0.5 は必要ありませんよね?)。

if not (x >= 0 and x <= 1 and math.floor(x) == x) then
    print( "X must be equal to 1 or 0" )
    return
end

私が書いたことに注意してくださいx >= 0 and x <= 1。上記の説明が理解できたなら、なぜ私が を書かなかったのか0 <= x <= 1、そしてこの誤った式が何を返すのかを説明できるはずです!

于 2012-07-25T22:44:54.743 に答える
10

2 つの値のみをテストするには、個人的には次のようにします。

if x ~= 0 and x ~= 1 then
    print( "X must be equal to 1 or 0" )
    return
end

2 つ以上の値に対してテストする必要がある場合は、次のように、セットのように機能するテーブルに選択肢を詰め込みます。

choices = {[0]=true, [1]=true, [3]=true, [5]=true, [7]=true, [11]=true}

if not choices[x] then
    print("x must be in the first six prime numbers")
    return
end
于 2012-07-25T21:46:12.063 に答える
5

x ~= 0 or 1と同じです((x ~= 0) or 1)

x ~=(0 or 1)と同じ(x ~= 0)です。

代わりにこのようなことを試してください。

function isNot0Or1(x)
    return (x ~= 0 and x ~= 1)
end

print( isNot0Or1(-1) == true )
print( isNot0Or1(0) == false )
print( isNot0Or1(1) == false )
于 2012-07-25T21:47:43.693 に答える