Что нового

Нестандартное использование тернарного оператора

veretragna

Как писал, так и работает.
Сообщения
140
Репутация
10
Дисклеймер. Этот пост - не просьба о помощи, а просто информация, которую я решил проверить с немного неожиданным результатом.

Думаю, здесь все читают справку и знают о тернарном операторе.
Обычно он используется, чтобы сократить блок условных операторов If... Then... Else ... EndIf, если сравнение простое и базируется на булевой логике: или условие истинно, выполняется первое условие, если нет - второе.

Пример:
Код:
Local $k = ""
If StringInStr("ababababac", "ac") then
  $k = 1
Else
  $k = 0
EndIf


С использованием тернарного оператора превращается в:
Код:
; если $k не равно нулю / истинно, присвоить переменной $k значение 1, иначе - 0
Local $k = StringInStr("ababababac", "ac") ? 1 : 0


Или очень удобно делать так:
Код:
; если программа скомпилирована, устанавливать иконку из ресурсов, а если нет - из папки
$Icon1 = GUICtrlCreateIcon(@Compiled ? @AutoItExe : @ScriptDir & "\graphics\1.ico", @Compiled ? -5 : -1, 160, 360, 32, 32)



Теперь о главном.
Оказывается, тернарный оператор можно использовать и в левой части выражения (подобно lvalue в с-подобных языках), но только в некоторых случаях и сильно ограничено.
Пример:
Код:
$k = 1
; если $k не равно нулю / истинно, запустить функцию _Function1, иначе - _Function2
$k ? _Function1() : _Function2()


А вот этот пример уже приведет к ошибке, или действие вообще не произойдет. Тут в левой части выражения тернарный оператор не работает.
Код:
; если $k не равно нулю / истинно, выбрать переменную $v1 и присвоить ей значение 1, иначе - выбрать переменную $v2 и присвоить ей значение 1
Local $k = 1, $v1, $v2
($k ? $v1 : $v2) = 1


Так и должно быть? В С++ ведь тернарный оператор работает и в левой, и в правой части выражения, а в AutoIt - только в правой и с ограничениями в левой.


Обновлено:
Благодаря товарищу Kaster'у все стало на свои места. В AutoIt тернарный оператор работает только в правой части выражения (rvalue).
Ссылка на сообщение.
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
veretragna [?]
Так и должно быть?
Это особенность C++ и, пожалуй, не из разряда полезных. К примеру, в C такое недопустимо.

Тернарная установка эквивалентна следующей функции: (если речь не идет о функциях)
Код:
Func _Iif($bCond, $x1, $x2)
	If $bCond Then _
		Return $x1

	Return $x2
EndFunc
 
Автор
veretragna

veretragna

Как писал, так и работает.
Сообщения
140
Репутация
10
А интерес, собственно говоря, чисто академический =)
Я просто поставил задачу испробовать границы его применимости, и оказалось, что в некоторых случаях он не работает.
Про функцию _Iif, а также про _IifEx в курсе, а в крайнем случае можно и самому нечто такое написать.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
veretragna
Код:
$k = 1
; если $k не равно нулю / истинно, запустить функцию _Function1, иначе - _Function2
$k ? _Function1() : _Function2()

синтаксически эквивалентно
Код:
$k = 1
; если $k не равно нулю / истинно, запустить функцию _Function1, иначе - _Function2
$val = $k ? _Function1() : _Function2()

так что тернарный оператор работает по правую сторону от оператора присваивания.
 
Автор
veretragna

veretragna

Как писал, так и работает.
Сообщения
140
Репутация
10
Kaster, спасибо!
Заново осмыслил механизм работы тернара.
Тема решена.
 
Верх