Добавлен , опубликован

Lua-программирование для чайников

Содержание:
Предисловие.
Логические выражения выполняют действие (или не одно), если вы полнилось какое-то другое действие (или, опять же, не одно).

6.1. Логические операторы.

Прежде чем переходить к изучению логических выражений (по-простому — условий), надо бегло пройтись по условным операторам. Вот все они:
not (не);
and (и);
or (или);
== (равно);
~= (не равно) вместо привычного многим != (тильда);
> (больше);
< (меньше);
>= (больше или равно);
<= (меньше или равно). 

6.2. Простейшие условия.

Самое простое условие выглядит так:
Синтаксис:
if ... then  
  ...  
end
Не стоит ничего объяснять — на примере всё станет понятно:
Пример:
if a then -- если переменная «а» существует  
  a = 1; -- тогда переменная имеет значение 1.  
end -- конец
Запись «if a then» эквивалентна «if a ~= nil then» (если «а» не равна nil). То есть просто идёт проверка на существование переменной в принципе.

6.3. Условия с «else».

«else» выполняет другое действие, если условие c «if» не выполнилось.
Пример:
a = 1;
if a == 1 then -- если переменная «а» равна единице  
  print("a is 1"); -- тогда..  
else -- если не выполнится  
  print("a is not 1"); -- тогда...  
end -- конец
Важно знать, что блок «else» всегда один (то есть два и более else не допустимы) и всегда ставится в конце других условий.

6.4. Условия с «elseif».

Блок «elseif» выполняет ряд других условий (или только одно), если предыдущие (или только одно) не выполнились.
Пример:
if a > 2 then -- если а больше двух  
  a = 3; -- тогда а равна трём  
elseif a < 2 then -- если же а меньше двух  
  a = 1; -- тогда а равна единице  
else -- иначе  
  a = nil; -- тогда удалить а  
end -- конец
Тут можно сразу вставить блок «else».
Блоков elseif может быть сколько угодно много. Располагаются они всегда после if и перед else (если он есть).

6.5. Оператор not.

Долго о нём разглагольствовать не надо. Просто отрицание какой-либо операции.
Пример:
if not a > 4 then  
  ...  
end
Хотя в данном примере лучше not a > 4 заменить на a <= 4.
Рассмотрим другой пример:
if not a then
  ...
end
Здесь проверятся несуществование переменной a. В данном случае эта переменная не указана, соответственно, условие выполнится.
Можно и так:
local flag = true

flag = not flag --меняем на противоположный параметр
if not flag then

end

6.6. Несколько условий в одном if/elseif.

Для этого есть операторы and и or:
if a and b and c then  
  ...  
end
Ни a, ни b, ни c не должны быть равны nil в данном примере. Если хоть одна переменная окажется равной nil, условие не выполнится.
Другое дело с or:
if a or b or c then  
  ...  
end
Условие не выполнится только в том случае, если все три переменные окажутся равны nil. Если хотя бы одна переменная окажется не равной nil, то условие выполнится.
Также бывают случаи, когда необходимо исключить из условия сразу несколько переменных, например a и b. Можно конечно сделать так:
if not a and not b and c then  
  ...  
end
Но есть более упрощённый вариант — использовать скобки:
if not (a and b) and c then  
  ...  
end
Так же можно поступить и с or:
if not (a or b) and c then  
  ...
end
С подобными вполне конструкциями можно поэкспериментировать.
А с elseif всё абсолютно идентично.

6.7. Функция rawequal.

Дополнительная функция, проверяющая равенство двух переменных. Возвращает тип данных boolean.
Пример:
a = 1;
b = 1;

if rawequal(a,b) == true then
  print(a+b); -- 2
end
Эквивалентно:
a = 1;  
b = 1;  

if a == b then  
  print(a+b); -- 2  
end

6.8 Булева

Хотел обратить еще внимание на одну вещь, которую автор позабыть написать.
  • Существует логический тип с двумя значениями: true и false.
  • В условном контексте ( if , elseif , while , until ) логическое значение (пример true/false) не требуется. Можно использовать любое выражение.
  • В условном контексте false и nil считаются ложными, а все остальное считается истинным.
  • Хотя 3 уже подразумевает это: если вы исходите из других языков, помните, что 0, а, пустая строка считается как true в условных контекстах в Lua.

Булевский тип

Булевы и другие значения
При работе с lua важно различать логические значения true и false и значения, которые оцениваются как true или false.
В lua есть только два значения, которые вычисляют false: nil и false , тогда как все остальное, включая числовое значение 0 оценивается как true.
Некоторые примеры того, что это означает:
local a
if a then --переменная a пустая, nil. В ней ничего не записано. Условие вернет false.

end

--можно даже записать так, чтобы условие сработало. Иногда необходимо проверять, например, таблица => иницирована (не пуста) она у юнита/игрока или нет. Если нет, то создаем новую таблицу:
if not a then
	a = {} --так инициируют таблицу, но об этом позже.
end
А теперь давайте-ка запишем в переменную любое значение:
local a = 1
local b = -1
local s1 = "Hello!"
local s2 = ""

if a then print("a is true") end --Условие a вернет true.
if b then print("b is true") end --Условие b вернет true.
if s1 then print("s1 is true") end --Условие s1 вернет true.
if s2 then print("s2 is true") end --Условие s2 вернет true, несмотря на то, что строка пуста "".
if 0 then print("0 is true") end --> Условие вернет true, несмотря на то, что туда ввели нолик
if (2 == 3) then print("true") else print("false") end --> this prints "false"
if (2 == 3) == false then print("true") end --> this prints "true"
if (2 == 3) == nil then else print("false") end --> prints false, because even if nil and false both evaluate to false, they are still different things.

тернарные выражения

Логические операторы в lua необязательно возвращают логические значения:
and вернет второе значение, если первое значение будет равно true;
or возвращает второе значение, если первое значение имеет значение false;
Это позволяет моделировать тернарный оператор, как и на других языках (смотрим вниз):
Есть вот такой не красивый код, но дело в его удобстве. Все мы привыкли через каждую строчку писать с отступами с далекого варкрафта.
if a>3 then
  c = 1
else
  c = 0
end
Однако, когда у вас слишком большие тексты, лучше сократить и записать в одну строчку. Как записать все в одну строку? C+ это есть. В луа как то
c=a>3 and 1 or 0
Примеры:
local var = false and 20 or 30 --> вернет 30
local var = true and 20 or 30 --> вернет 20
-- в языке C+ это можно записать как:  local var = false ? 20 : 30
Это также можно использовать для инициализации таблиц, если они не существуют
tab = tab or {} -- Если таблица tab пуста, то создаем новую таблицу tab = {}
Или функция конверта цветов из отсюда
function Vector(x,y,z)
	return x or 0, y or 0, z or 0
end

--в луа есть особенность, когда можно последний аргумент не прописывать. Он будет пустым nil. 
print(Vector(1, 1)) --вернет точку (1,1,0)
Или же есть замечательная функция, которая возвращает знак:
function math.sign(value) 
	if value < 0 then
	  return -1
	elseif value >0 then
	  return 1
	else
	  return 0
	end
end
Выглядит очень не красиво, можно заменить на:
function math.sign(value) 
return value < 0 and -1 or value > 0 and 1 or 0 
end
таким образом можно избегать использования операторов if, делая код более удобным для чтения
Единственный случай, когда это не применяется, - это когда переменная хранит значение false , и в этом случае оно технически существует, но все равно оценивается как false. Из-за этого плохой дизайн создает функции, которые возвращают false и nil зависимости от состояния или ввода. Мы все еще можем проверить, есть ли у нас nil или false :
if nil == nil then print("A nil is present") else print("A nil is not present") end
if false == nil then print("A nil is present") else print("A nil is not present") end
-- The output of these calls are:
-- A nil is present!
-- A nil is not present

Логические операторы

В Lua логические операции можно манипулировать с помощью логических операторов . К этим операторам относятся not , and , и / or .
В простых выражениях результаты довольно просты:
print(not true) --> false
print(not false) --> true
print(true or false) --> true
print(false and true) --> false

Приказ о приоритете

Порядок приоритета подобен математическим операторам унарный - , * и + :
  • [not]
  • затем [and]
  • затем [or]
Это может привести к сложным выражениям:
print(true and false or not false and not true)
print( (true and false) or ((not false) and (not true)) )
    --> these are equivalent, and both evaluate to false

Краткосрочная оценка

Операторы and or могут быть оценены только с помощью первого операнда, если вторая не нужна:
function a()
    print("a() was called")
    return true
end

function b()
    print("b() was called")
    return false
end

print(a() or b())
    --> a() was called
    --> true
    --  nothing else
print(b() and a())
    --> b() was called
    --> false
    --  nothing else
print(a() and b())
    --> a() was called
    --> b() was called
    --> false

Идиоматический условный оператор

Из - за приоритет логических операторов, возможность для оценки короткой резки и оценки , не являющихся false и не- nil значений , как true , идиоматический условный оператор доступны в Lua:
function a()
    print("a() was called")
    return false
end
function b()
    print("b() was called")
    return true
end
function c()
    print("c() was called")
    return 7
end

print(a() and b() or c())
    --> a() was called
    --> c() was called
    --> 7
    
print(b() and c() or a())
    --> b() was called
    --> c() was called
    --> 7
Кроме того , в связи с характером x and a or b структуры, никогда не будет возвращен , если она принимает значение a false , это условное будет всегда возвращать b , независимо от того , что x есть.
print(true and false or 1)  -- outputs 1

Таблицы правды

Логические операторы в Lua не возвращают логическое значение, а один из аргументов. Используя nil для false и числа для true, вот как они себя ведут.
print(nil and nil)       -- nil
print(nil and 2)         -- nil
print(1 and nil)         -- nil
print(1 and 2)           -- 2

print(nil or nil)        -- nil
print(nil or 2)          -- 2
print(1 or nil)          -- 1
print(1 or 2)            -- 1
Как вы можете видеть, Lua всегда будет возвращать первое значение, которое делает проверку неудачной или успешной . Вот таблицы правды, показывающие это.
  x  |  y  || and            x  |  y  || or
------------------         ------------------
false|false||  x           false|false||  y   
false|true ||  x           false|true ||  y   
true |false||  y           true |false||  x   
true |true ||  y           true |true ||  x
Для тех, кто в ней нуждается, вот две функции, представляющие эти логические операторы.
function exampleAnd(value1, value2)
  if value1 then
    return value2
  end
  return value1
end

function exampleOr(value1, value2)
  if value1 then
    return value1
  end
  return value2
end

`
ОЖИДАНИЕ РЕКЛАМЫ...
1
37
2 года назад
Отредактирован ScorpioT1000
1
Забыл про тернарные выражения:
local number = (x > 0) and x or y
Забыл про условное присваивание:
local number = x or y
0
27
2 года назад
0
Забыл про тернарные выражения:
local number = (x > 0) and x or y
Забыл про условное присваивание:
local number = x or y
Добавим)) на телефоне неудобно
0
6
2 года назад
Отредактирован Lasto4ka
0
if a and b and c then  
  ...  
end
Там ниже по тексту говорится только про nil. Но забыл, что false тоже как nil будет воспринят. Т.е.:
if false then
-- и
if nil then
Это одно и то же - внутрь условие не попадешь, потому что оно ложное
0
6
2 года назад
0
  • 6.7. Функция rawequal без введения в метатаблицы тут вообще не к месту. Лучше убрать.
  • 6.9. "Хотя 3 уже подразумевает это: если вы исходите из других языков, помните, что 0, а, пустая строка считается как true в условных контекстах в Lua." - может "что 0 и пустая строка"?
Таблицы истинности, а не правды. Далее: "Как вы можете видеть," вообще-то "Как видите", без кальки с английского 😤
А вот и оригинал: riptutorial.com/lua/example/13833/truth-tables
Чтобы оставить комментарий, пожалуйста, войдите на сайт.