Значения по умолчанию
Операторы and и or умеют больше, чем соединять условия. Они возвращают не просто true или false, а одно из двух своих значений. a or b возвращает a, если a считается истиной, а иначе b:
print(nil or "друг")
print("Эмма" or "друг")
print(0 or 12)Программа выведет:
друг
Эмма
0Благодаря этому or отлично подходит для значения по умолчанию: значения, которое берут, когда переменная равна nil. Торговец Гуго может назвать Эмме цену тыквы, а может и не назвать:
local hugoPrice
local price = hugoPrice or 20
print("Цена тыквы: " .. price)Программа выведет:
Цена тыквы: 20hugoPrice равно nil, поэтому price получает значение по умолчанию, 20. Если бы Гуго назвал 25, в price оказалось бы 25. Читайте это как «цена Гуго, а если её нет — 20». Но помните последнюю строку первого примера: or заменяет только nil и false. 0 считается истиной, поэтому 0 or 12 — это 0.
Lua выполняет or последним, после всех остальных операторов, включая ... В более длинном выражении берите его в скобки: "Цена: " .. (hugoPrice or 20). Без них "Цена: " .. hugoPrice or 20 сначала попытается присоединить к строке nil и закончится ошибкой attempt to concatenate a nil value (local 'hugoPrice').
a and b работает наоборот: если a считается ложью, возвращается a, а иначе b. Вместе condition and x or y возвращает x, если условие истинно, и y, если нет, то есть получается маленький if с else в одной строке:
local eggs = 14
local box = eggs >= 12 and "полную коробку" or "половину коробки"
print("Эмма упаковывает " .. box)Программа выведет:
Эмма упаковывает полную коробкуСравнение истинно, поэтому eggs >= 12 and "полную коробку" возвращает "полную коробку", а "полную коробку" or "половину коробки" возвращает "полную коробку", ведь строка считается истиной. При 8 яйцах сравнение вернуло бы false, false and … вернуло бы false, а false or "половину коробки" вернуло бы "половину коробки".
Этот приём ломается, если значение посередине — false или nil:
local isRaining = true
local needsWater = isRaining and false or true
print(needsWater)Программа выведет:
trueИдёт дождь, значит, поле не должно нуждаться в поливе. Но isRaining and false возвращает false, а false or true возвращает true. Используйте condition and x or y только тогда, когда x не может быть false или nil, например строка или число. В остальных случаях пишите if с else (а здесь можно просто not isRaining).
Задание
- 1
Запустите программу: она завершается с ошибкой, потому что
customerравноnil. С помощьюorсделайте так, чтобы покупателя без имени программа благодарила какдруг. Тогда программа выведет:Яиц: 6 Спасибо, друг! - 2
Одно яйцо стоит 3 монеты, но покупатель, который берёт 10 яиц или больше, платит за каждое всего 2 монеты. Между двумя строками с
printсоздайте локальную переменнуюpricePerEgg, которая равна2, еслиeggsне меньше10, и3в остальных случаях. Запишите это в одну строку с помощьюandиor. Затем выведите цену всех яиц. Программа выведет:Яиц: 6 Цена в монетах: 18 Спасибо, друг! - 3
Дедушка Джо пришёл за 10 яйцами: замените
customerна"дедушка Джо", аeggsна10. Программа выведет:Яиц: 10 Цена в монетах: 20 Спасибо, дедушка Джо!