Re[4]: ?: - оператор Элвис - знали ли вы?
От: velkin Удмуртия https://kisa.biz
Дата: 01.01.25 19:59
Оценка: 1 (1)
Здравствуйте, Shmj, Вы писали:

S>Вы что не переходили по ссылке? Тернарный оператор — это другое.

S>Тернарный оператор:
S>
S>int result = (a > b) ? a : b;
S>

S>Оператор Элвис:
S>
S>val result = user.name ?: "Unknown"
S>

Давай перейдём и посмотрим.

Нотация оператора Элвиса была вдохновлена ​​тернарным условным оператором, ? :, поскольку выражение оператора Элвиса A ?: B приблизительно эквивалентно тернарному условному выражению A ? A : B.
...
Булев вариант
На языке, поддерживающем оператор Элвиса, что-то вроде этого:
x = f() ?: g()
установит x равным результату , f() если этот результат истинен, и результату в g()противном случае.

Это эквивалентно следующему примеру, использующему условный тернарный оператор:
x = f() ? f() : g()
за исключением того, что он не оценивается f() дважды, если дает истину. Обратите внимание на возможность произвольного поведения, если f() это не функция, независимая от состояния, которая всегда возвращает один и тот же результат.
...
В GNU C и C++ (то есть в C и C++ с расширениями GCC ) второй операнд тернарного оператора является необязательным. Так было по крайней мере с версии GCC 2.95.3 (март 2001 г.), и, по-видимому, это изначальный оператор Элвиса.
...
В C# оператор null-conditional называется ?. "оператором Элвиса", но он не выполняет ту же функцию. Вместо этого ее выполняет оператор null-coalescing ??.


Ладно давай просто проверим на GCC C++, то есть g++.
#include <iostream>

int main()
{
    int a = 5, b = 3;
    int min = (a < b) ? a : b;
    int max = (a > b) ? a : b;
    std::cout << "min = " << min << std::endl;
    std::cout << "max = " << max << std::endl;
    
    // elvis ???
    int min1 = (a < b) ?: b;
    int max1 = (a > b) ?: b;
    // warning: the omitted middle operand in ?: will always be 'true',
    // suggest explicit middle operand
    std::cout << "min1 = " << min1 << std::endl;
    // warning: the omitted middle operand in ?: will always be 'true',
    // suggest explicit middle operand
    std::cout << "max1 = " << max1 << std::endl;
    
    // reverse elvis ???
    // error: expected primary-expression before ';' token
    //int min2 = (a < b) ? a :;
    // error: expected primary-expression before ';' token
    //int max2 = (a > b) ? a :;
}


Вывод.
min = 3
max = 5
min1 = 3
max1 = 1


Я сократил переведённую справку "элвиса" до C++ и C#, но вообще.

В GNU C и C++ (то есть в C и C++ с расширениями GCC) второй операнд тернарного оператора является необязательным. Так было по крайней мере с версии GCC 2.95.3 (март 2001 г.), и, по-видимому, это изначальный оператор Элвиса.

В Apache Groovy «оператор Элвиса» ?: документирован как отдельный оператор; эта функция была добавлена ​​в Groovy 1.5 (декабрь 2007 г.). Groovy, в отличие от GNU C и PHP, не ?: позволяет просто опускать второй операнд тернарного оператора ; вместо этого двоичный оператор ?: должен быть записан как один оператор без пробелов между ними.

В PHP можно опустить среднюю часть тернарного оператора, начиная с версии PHP 5.3. (июнь 2009 г.).
В языке программирования Fantom есть ?: бинарный оператор, который сравнивает свой первый операнд с null.

В Kotlin оператор Elvis возвращает свою левую часть, если она не равна нулю, и свою правую часть в противном случае. Распространенным шаблоном является использование его с return, например: val foo = bar() ?: return

В Gosu оператор ?: возвращает правый операнд, если левый также равен нулю.

В C# оператор null-conditional называется ?. "оператором Элвиса", но он не выполняет ту же функцию. Вместо этого ее выполняет оператор null-coalescing ??.

В ColdFusion и CFML оператор Элвиса был введен с использованием ?: синтаксиса.

В языке программирования Xtend есть оператор Элвиса.

В шаблонах закрытия Google оператор Элвиса является нулевым объединяющим оператором , эквивалентным isNonnull($a) ? $a : $b.

В Ballerina оператор Elvis L ?: R возвращает значение, L если оно не равно нулю. В противном случае возвращает значение R.

В JavaScript оператор объединения nullish (??) является логическим оператором, который возвращает свой правый операнд, если его левый операнд равен null или undefined, а в противном случае возвращает свой левый операнд.


Получается изначально взяли тернарную условную операцию, сократили со значением по умолчанию, но под сокращением каждый новый язык программирования стал понимать нечто своё. И это нас так же подводит к Null coalescing operator. А этот Элвис может быть чем угодно, главное чтобы знаки совпадали ?: или даже не совпадали.

Примерно понятно, что в C и C++ это тернарная (синонимы: тринарная, троичная, трёхчленная) условная операция, но каждый создатель нового языка потом додумал нечто своё, если не задать в ней второй аргумент из трёх и в принципе что с чем сравнивать в условии, то есть в первом аргументе. При этом в C++ как я сейчас проверил можно не задать второй член, но не третий.

Это мне напоминает "И одним лёгким движением руки тернарная условная операция превращается, превращается, в ...". А во что угодно, главное чтобы был ?: или не был. Как-то всё это не надёжно, хотя может на частной тусовке смузи программистов и прокатит.