Всё, что мы могли написать до настоящего момента - это последовательность инструкций, которые прямолинейно исполняются интерпретатором. Для того, чтобы сделать процесс исполнения программы более нелинейным - например, пропускать некоторые фрагменты кода при определённых условиях - существует управляющая конструкция if. Описывается подобным образом:
Код
if <условие> then <инструкции> end
Условием может быть любое логическое выражение: то есть, утверждение, которое может быть либо ложным, либо истинным. Если условие истинно, то инструкции между then и end исполняются, если нет - пропускаются. Например:
Код
if x > 0 then print("x is positive") end
Читать этот код следует как: "если значение переменной х больше, чем 0, то вывести на экран: х - положительный". Соответственно, если х меньше либо равно нулю, то ничего выведено не будет, инструкция просто проигнорируется. Выражение x > 0 возвращает одно из двух значений логического типа: true (истина) или false (ложь). Вообще, что делает оператор ">": он берёт значения слева и справа и проверяет, больше ли значение слева чем значение справа, и возвращает true в случае, если это так, и false в случае, если это не так. Можно даже попробовать вывести на экран результат сравнения:
Код
print(2 > 3, 3 > 2) -- Выводит: -- false true
Существуют и другие операторы сравнения: "<" - меньше, ">=" - больше либо равно, "<=" - меньше либо равно, "~=" - не равно, "==" - строго равно. Они работают именно так, как человек как минимум с пятью классами образования мог ожидать:
print( 1 <= 1, 4 >= 3, (99-98.9) ~= 0, 58 == 85 ) -- true true true false -- Не путайте операторы "=" и "=="! -- "=" используется для присваивания переменным значений -- "==" используется для __сравнения__ двух значений
Таким образом, вы можете использовать все эти операции сравнения в условии if:
Код
-- cmp9to10.lua--
if 9 ~= 10 then print("9 doesn't equal 10!") end -- Выведет: 9 doesn't equal 10!
if 9 == 10 then print("2 equals 10!") end -- Ничего не выведет, и это правильно
Два раза сравнивать два числа? Перебор! Пример, приведённый выше, можно переписать:
Код
-- smartcmp9to10.lua--
if 9 ~= 10 then print("9 doesn't equal 10!") else print("2 equals 10!") end -- Выведет: 9 doesn't equal 10!
Структура if-else позволяет не просто проигнорировать кусок кода, а выбрать для исполнения одну из двух последовательностей инструкций. Пример читается: "Если девять не равно десяти, то вывести: 9 не равно 10, иначе - вывести: 9 равно десяти". Удобно, да? Теперь можно расширить самый верхний пример:
Код
if x > 0 then print("x is positive") else print("x is negative") end
Красота, да и только! Теперь мы можем написать очень умную программу, которая определяет знак числа. Задайте переменной x различные значения (т.е. допишите наl if'ом что-то вроде x = <ваше_любимое_число>) и посмотрите, как программа на них реагирует.
Что? Вы написали 0, и программа вывела: x is negative? С каких это пор у нуля есть знак? Наша программа не выдерживает критики, и если бы мы писали её за деньги какому-нибудь клиенту, он бы потребовал выплатить компенсацию. Так как платить мы не хотим, стоит добавить дополнительную проверку с помощью инструкции elseif. Вроде того:
Код
if x > 0 then print('x is positive') elseif x < 0 then print('x is negative') else print('x is zero') end
elseif всегда принимает дополнительное условие для проверки, в отличие от else, который всегда стоит один-одинёшенек. Фрагмент выше читается: "если значение х больше нуля, вывести: х - положительный. Если же х меньше нуля, то вывести: х - отрицательный. А уж ежели ни то, ни другое, то вывести: х равен нулю".
Веток elseif вы можете написать сколько угодно. Взгляните, например, на эту внушающую ужас постройку:
Код
if x == 1 then print('one') elseif x == 2 then print('two') elseif x == 3 then print('three') elseif x == 4 then print('four') elseif x == 5 then print('five') elseif x == 6 then print('six') elseif x == 7 then print('seven') elseif x == 8 then print('eight') elseif x == 9 then print('nine') elseif x == 0 then print('zero') end -- Здесь ветка else опущена
Что твой небоскрёб! Кстати, заметили? Я в последних двух примерах заключил параметры для print'ов в одинарные кавычки. Это не ошибка, так тоже можно записывать строковые литералы в Lua. "STRING" это же самое, что и 'STRING'. Различия вы узнаете в более поздних уроках, а пока проверьте:
Код
print('STRING' == "STRING") -- Выведет true. -- О сравнении строк вы также узнаете позднее.
А что если мы решаем задачу с интервалами? Что если нам нужно проверить, укладывается ли переменная в какой-то предел? Например, играть в настольную игру Cluedo могут от двух до шести человек. Допустим, в переменной players хранится число игроков (надеемся, положительное целое), которые хотят играть. Как мы проверим, сможет ли состояться игра при заданном числе желающих? Один вариант так и напрашивается:
Код
if players >=2 then if players <=6 then print("Ok, you can play!") end end
На первый взгляд, сносное решение, но, если подумать, не очень гибкое. И громоздкое, к тому же. Хотелось бы оставить один if вместо двух. И мы можем так сделать с помощью логического оператора and:
Код
if players >= 2 and players <= 6 then print 'Ok, you can play!' else print 'No way, buddies!' end
Читается: "если количество игроков больше либо равно двум и меньше либо равно шести, то играть можно, иначе играть нельзя."
Заметьте, что написать 2 <= players <= 6 не получится, хотя в школе и учили, что так правильно. Не получится потому, что интерпретатор сперва сравнит 2 и players. Если players равняется, например, 3, то тогда сравнение даст значение true, после чего выражение выродится в true <= 6. Можете сказать, что больше: шесть или истина? Не знаю, как вы, а Lua не может.
Суть работы оператора and состоит в том, что он берёт два операнда (два значения: слева и справа) и возвращает true, если оба они истинные, или false, если хотя бы один из них ложный. and - не единственный логический оператор, у него есть друзья: or и not. Работа каждого из них пояснена ниже:
Код
-- and возвращает true, если и первый, и второй операнды истинны -- также известен как: "и", конъюнкция, логическое умножение true and true -> true true and false -> false false and true -> false false and false -> false
-- or возвращает true, если хотя бы один из операндов истинен -- (или левый, или правый, или оба сразу) -- также известен как: "или", дизъюнкция, логическое сложение true or true -> true true or false -> true false or true -> true false or false -> false
-- not принимает только один операнд и инвертирует его -- также известен как: "не", инверсия not true -> false -- ложь - не истина! not false -> true -- истина - не ложь!
С использованием операторов or и not пример с игроками в Cluedo можно переписать так:
Код
if not (players < 2 or players > 6) then print 'Ok, you can play!' else print 'No way, buddies!' end
И работать он будет точно так же. Только читается по-другому: "если количество игроков не меньше двух и не больше шести, то играть можно, иначе играть нельзя."
Кстати, true и false - такие же обычные значения, как числа и строки, их можно присваивать переменным! Переменные, имеющие логическое значение true или false, на программистском жаргоне часто называются флагами, наподобие флажков на американских почтовых ящиках. Флажок поднят (true) - почта пришла, флажок опущен (false) - почты нет.
В программах флаги используют подобным образом:
Код
-- mailbox.lua -- flag = true
if flag then print "You've got mail" end
Заметьте, что сравнивать flag с true необязательно: его значение уже имеет логический тип.
Как вы догадались, из логических переменных и логических операторов тоже можно строить выражения, большие и не очень.
-- Выясняем, смертен ли Сократ. -- Заметьте, что здесь if-else записан несколько по-другому, -- но на его работу это не влияет. if socrates_is_mortal then print("Socrates is mortal") else print("Socrates is immortal") end
jack = (1 >= 0) frost = true or jack madness = (jack and not frost) or not (frost and not jack) and true -- Попробуйте посмотреть, что из этого выйдет, сами!
Как в прошлый раз, в конце урока мы вспоминаем про nil. Никогда не забывайте про nil! Очень много ходовых приёмов программирования на Lua основано на махинациях с этим значением.
Во-первых, если не считать одно исключение, в контексте логических операций nil трактуется как false. Таким образом:
Код
-- nillogics.lua --
print(true and nil) -- Выведет false
print(true or nil) -- Выведет true
print(not nil) -- Выведет true
existent = true print(nonexistent or existent) -- Выведет true
-- Однако !! print(nil and nil, nil or nil) -- Выведет nil nil -- Если оба операнда and или or равны nil, то и результат равен nil
Во-вторых, нелогическое значение в условии if трактуется как истинное, если оно не равно nil, и как ложное, если оно равно nil.
Код
-- nillogics2.lua --
value1 = "OK" value2 = 1.6180339887 value3 = nil
if value1 then print "This works." end
if value2 then print "This works, too." end
if value3 then print "This doen't work." end
if value4 then -- Не забывайте: несуществующая переменная имеет значение nil print "Neither does this." end
-- Этот фрагмент может вызвать недоумение программистов на С, -- но он совершенно корректен, так как 0 не равен nil. if 0 then print "And this does work." end
nillogics2.lua выведет: This works. This works, too. And this does work. Таким манером мы можем, например, избежать выполнения операций над неинициализированными (равными nil) значениями, поскольку такие операции могут "положить" программу. Держите это в голове, в будущем это знание нам пригодится.
Резюме: 1. Мы узнали, как создавать условные ветвления в программе на Lua. 2. Узнали, какие есть операторы сравнения, логические операторы, какие выражения мы можем с ними написать и где их использовать. 3. Узнали о новой ипостаси значения nil как аналога значения false. Поняли, что nil всё ещё гораздо глубже, чем мы думали.
Как и в прошлый раз, вот несколько упражнений для желающих упражняться. 1. Существует действительная переменная p (то есть, её значение - число, которое может быть целым или дробным, положительным, отрицательным или равным нулю). С помощью управляющей конструкции if напишите программу, которая проверяет, является ли значение p корректным значением вероятности: оно должно попадать в интервал [0, 1]. 2. Создайте программу, которая реализует операцию "исключающее или". В начале у вас должно быть объявлено две переменные с логическим значением: a и b, в конце вы должны получить переменную с, равную true, если лишь одна из переменных a и b равна true, и false в любом другом случае. Удачи!
Также если вы считаете, что данный материал мог быть интересен и полезен кому-то из ваших друзей, то вы бы могли посоветовать его, отправив сообщение на e-mail друга:
Игровые объявления и предложения:
Если вас заинтересовал материал «Lua для всей семьи. Урок 2: условные ветвления и логика», и вы бы хотели прочесть что-то на эту же тему, то вы можете воспользоваться списком схожих материалов ниже. Данный список сформирован автоматически по тематическим меткам раздела.
Предлагаются такие схожие материалы:
Если вы ведёте свой блог, микроблог, либо участвуете в какой-то популярной социальной сети, то вы можете быстро поделиться данной заметкой со своими друзьями и посетителями.