Я люблю Lua. I love Lua.

Тернарный оператор

Posted in Uncategorized by ilovelua on Сентябрь 22, 2010

Взято отсюда.

Иногда при скриптинге в Lua встречается следующая конструкция:

if condition then
s = "on"
else
s = "off"
end

В большинстве языков подобная запись легко заменяется тернарным оператором:

s = condition ? "on" : "off"

Однако в Lua тернарный оператор отсутствует. Но не оставлять же такую громоздкую конструкцию?

Выход прост — к нам придут на помощь логические операторы or и and. В Lua для них выполняется следующее:
оператор and возвращает первое ложное значение среди сових операндов; если оба операнда истинны, возвращается последний из них
оператор or возвращает первое истинное значение среди своих операндов; если оба операнда ложны, возвращается последний из них
Следуя этой нехитрой логике можно записать следующую конструкцию:

s = condition and "on" or "off"

В самом деле, or имеет более низкий приоритет, и поэтому сначала выполняется контрукция с and. Если условие condition истинно, то по логике оператора and возвращается его второй аргумент («on»). Строчка истинна, и поэтому or возвращает ее как результат всего выражения.

Если же уcловие condition ложно, то оператор and возвращает ложь, и оператор or, получив ложь в качестве первого операнда, возвращает значение второго («off»).

Таким образом, в результате махинаций с логическими операторами мы получили тернарный оператор в Lua!

Внимание! В комментариях приведен пример, в котором эта конструкция работает неправильно!

Advertisements

комментариев 7

Subscribe to comments with RSS.

  1. Alexander Gladysh said, on Сентябрь 22, 2010 at 8:58 дп

    Аккуратнее с этими вещами.

    a = true
    b = false — or nil
    c = «oops»
    s = a and b or c
    print(s) —> oops

    • Green Dog said, on Декабрь 6, 2012 at 1:09 пп

      хоть и некропост.

      а что Вас не устроило:
      a = true
      b = false — or nil
      c = “oops” — or true
      s = true and false or true — false or true = true

    • Sir Lua said, on Январь 17, 2017 at 11:53 дп

      Если у вас b — булево, а c — строка, значит вам стоит подумать над архитектурой вашей программной логики. То же самое касается и b = nil: если что-то возвращает nil, значит это можно и нужно делать не через тернарный оператор, а другими средствами. А если возвращение nil заранее предопределено, то просто ставьте его не на место b, а на место c. Ну а если у вас и b, и c — булевы, тернарный оператор вам не нужен. Так что такой способ вполне удобен для практических нужд. Главное помнить, что тернарный оператор должен возвращать ТОЛЬКО «true»-значения — числа, строки, таблицы, объекты. P.S. ПОХ НА НЕКРОПОСТ, такие статьи нужны чтобы их читали и через год и через 10 лет.

  2. ilovelua said, on Сентябрь 22, 2010 at 9:29 дп

    Да, Вы правы.

    отсюда: http://lua-users.org/wiki/TernaryOperator

    A somewhat inefficient «replacement» solution in Lua 5.1 using tables is

    local condition = true
    local a = false
    local b = true

    local x = (condition and {a} or {b})[1]
    print(x) —> false

    Это работает правильно. Но, как написано выше, неэффективно.

  3. Valery said, on Сентябрь 24, 2010 at 11:20 дп

    Скрипты зачастую молча позволяют делать неправильные вещи. IMHO далеко уходить от явных и прозрачных конструкций следует лишь в поисках приключений 🙂

  4. reimu said, on Август 5, 2011 at 6:18 пп

    Ну чем не угодило, блин? 😀

    function if2(cond, a, b)
    if cond then
    return a
    else
    return b
    end
    end

    Правда, a и b вычислятся оба, независимо от cond.

  5. ilovelua said, on Август 8, 2011 at 7:18 дп

    Ты действительно не видишь разницы между твоей функцией и

    s = condition and "on" or "off"

    Подсказка: они отличаются, например, длиной.


Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

%d такие блоггеры, как: