Встроенные условия в Lua (a == b? "Yes": "no")?
Есть ли способ использовать встроенные условия в Lua?
Такие как:
print("blah: " .. (a == true ? "blah" : "nahblah"))
8 ответов
Если a and t or f
не работает для вас, вы всегда можете просто создать функцию:
function ternary ( cond , T , F )
if cond then return T else return F end
end
print("blah: " .. ternary(a == true ,"blah" ,"nahblah"))
конечно, у вас есть недостаток, что T и F всегда вычисляются.... чтобы обойти это, вам нужно предоставить функции для вашей троичной функции, и это может стать громоздким:
function ternary ( cond , T , F , ...)
if cond then return T(...) else return F(...) end
end
print("blah: " .. ternary(a == true ,function() return "blah" end ,function() return "nahblah" end))
Обычно вы можете сделать:
condition and ifTrue or ifFalse
но это не обязательно лучший способ сделать это. Основная причина в том, что если это ложное значение (иногда),
ifFalse
будет оценивать, даже если
condition
является истинным значением. Один из способов сделать это просто без дополнительной работы:
(condition and {ifTrue} or {ifFalse})[1]
преимущество которого состоит не только в том, что оно является выражением и не связано с проблемой
ifTrue
быть ложным, что означает, что он может обрабатывать все случаи, но также имеет преимущество короткого замыкания (без оценки другого выражения). Нет необходимости в дополнительных функциях или возиться со сложными аспектами Lua.
На liki-users wiki есть хорошая статья о троичном операторе, вместе с объяснением проблемы и несколькими решениями.
Хотя этот вопрос довольно старый, я подумал, что было бы справедливо предложить другую альтернативу, которая синтаксически выглядит очень похожей на таковую тернарного оператора.
Добавь это:
function register(...)
local args = {...}
for i = 1, select('#', ...) do
debug.setmetatable(args[i], {
__call = function(condition, valueOnTrue, valueOnFalse)
if condition then
return valueOnTrue
else
return valueOnFalse
end
end
})
end
end
-- Register the required types (nil, boolean, number, string)
register(nil, true, 0, '')
А затем используйте это так:
print((true) (false, true)) -- Prints 'false'
print((false) (false, true)) -- Prints 'true'
print((nil) (true, false)) -- Prints 'false'
print((0) (true, false)) -- Prints 'true'
print(('') (true, false)) -- Prints 'true'
Примечание. Для таблиц, однако, вы не можете использовать их напрямую с помощью вышеуказанного метода. Это связано с тем, что каждая таблица имеет свою собственную независимую метатаблицу, а Lua не позволяет вам изменять все таблицы одновременно.
В нашем случае простым решением было бы преобразовать таблицу в логическое значение с помощью
not not
обманывать:print((not not {}) (true, false)) -- Prints 'true'
Lua намеренно облегчен, поэтому в нем нет тернарного оператора.
Есть несколько способов обойти это, включая использование идиомы «и/или». Но я думаю, что это плохо по нескольким причинам. В основном потому, что новички этого не понимают.
Я предлагаю использовать функцию:
local function choice(c, t, f)
return c and t or f
end
local s = choice(2 % 2 == 0, "even", "odd")
Вы можете просто написать оператор if в одной строке, это не стенографический, встроенный или тернарный оператор.
if (dummy == true) then
print("dummy is true")
end
тоже равно
if (dummy = true) then print("dummy is true") end
Веселись :D
local n = 12
do
local x = (n>15)
and print(">15")
or n>13
and print(">13")
or n>5
and print(">5")
end