Подтвердить что ты не робот

Не равный этому ИЛИ Что в Lua

Я пытаюсь проверить, что переменная НЕ равна тому или иному. Я попытался использовать следующие коды, но не работает:

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

Есть ли способ сделать это?

4b9b3361

Ответ 1

Ваша проблема связана с непониманием оператора or, который является общим для людей, изучающих языки программирования, подобные этому. Да, ваша непосредственная проблема может быть решена путем написания x ~= 0 and x ~= 1, но я расскажу немного подробнее о том, почему ваше попытка решения не работает.

Когда вы читаете x ~=(0 or 1) или x ~= 0 or 1, это естественно, чтобы анализировать это так же, как предложение "x не равно нулю или одному". В обычном понимании этого утверждения "х" является субъектом, "не равно" - это предикатная или глагольная фраза, а "ноль или один" - это объект, набор возможностей, соединенных конъюнкцией. Вы применяете объект с глаголом к ​​каждому элементу в наборе.

Однако Lua не анализирует это на основе правил грамматики английского языка, он анализирует его в бинарных сравнениях двух элементов на основе его порядка операций. Каждый оператор имеет приоритет, который определяет порядок, в котором он будет оцениваться. or имеет более низкий приоритет, чем ~=, так же как добавление в математике имеет более низкий приоритет, чем умножение. Все имеет более низкий приоритет, чем круглые скобки.

В результате при оценке x ~=(0 or 1) интерпретатор сначала вычислит 0 or 1 (из-за круглых скобок), а затем x ~= результат первого вычисления, а во втором примере он вычислит x ~= 0, а затем применить результат этого вычисления к or 1.

логический оператор or "возвращает свой первый аргумент, если это значение отличается от nil и false, иначе или возвращает его второе аргумент". Оператор реляционный оператор ~= является обратным оператору равенства ==; он возвращает true, если его аргументы являются разными типами (x - число, правильно?) и в противном случае обычно сравнивает его аргументы.

Используя эти правила, x ~=(0 or 1) будет разлагаться на x ~= 0 (после применения оператора or), и это вернет 'true', если x - это что-то другое, кроме 0, включая 1, что нежелательно. Другая форма x ~= 0 or 1 сначала оценит x ~= 0 (которая может возвращать true или false, в зависимости от значения x). Затем он разложится на один из false or 1 или true or 1. В первом случае оператор вернет 1, а во втором случае оператор вернет true. Поскольку структуры управления в Lua рассматривают только nil и false как ложные, а что-то еще, чтобы быть истинными, это всегда будет вводить оператор if, который не является тем, что вы хотите.

Невозможно использовать бинарные операторы, такие как предоставленные в языках программирования, для сравнения одной переменной со списком значений. Вместо этого вам нужно сравнить переменную с каждым значением по одному. Есть несколько способов сделать это. Самый простой способ - использовать законы Де Моргана, чтобы выразить утверждение "не одно или равно нулю" (которое нельзя оценить с помощью двоичных операторов) как "не одно, а не ноль", которое тривиально записывается двоичными операторами:

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, и что это ошибочное выражение вернется!

Ответ 2

Для тестирования только двух значений я лично сделал бы это:

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

Если вам нужно протестировать более двух значений, я бы использовал ваши варианты в таблице, действующей как набор, например:

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

Ответ 3

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 )