Pergunta

Pessoalmente, sou um defensor do operador ternário:() ?:;Eu percebo que ele tem o seu lugar, mas encontrei muitos programadores que são completamente contra usá-lo, e alguns que o usam com muita frequência.

Quais são seus sentimentos sobre isso?Que código interessante você viu usando-o?

Foi útil?

Solução

Use -o para apenas expressões simples:

int a = (b > 10) ? c : d;

Não se encorrente ou ninho operadores ternários como difícil de ler e confusos:

int a = b > 10 ? c < 20 ? 50 : 80 : e == 2 ? 4 : 8;

Além disso, ao usar o operador ternário, considere a formatação do código de uma maneira que melhore a legibilidade:

int a = (b > 10) ? some_value                 
                 : another_value;

Outras dicas

Isso torna a depuração um pouco mais difícil, pois você não pode colocar pontos de interrupção em cada uma das subestões. Eu o uso raramente.

Eu os amo, especialmente em idiomas seguros.

Eu não vejo como isso:

int count = (condition) ? 1 : 0;

é mais difícil do que isso:

int count;

if (condition)
{
  count = 1;
} 
else
{
  count = 0;
}

Editar -

Eu argumentaria que os operadores ternários tornam tudo menos complexo e mais arrumado que a alternativa.

Acorrentado, estou bem - aninhado, nem tanto.

Eu tendo a usá-los mais em C simplesmente porque eles são uma instrução if que tem valor, então reduz repetições ou variáveis ​​desnecessárias:

x = (y < 100) ? "dog" :
    (y < 150) ? "cat" :
    (y < 300) ? "bar" : "baz";

em vez de

     if (y < 100) { x = "dog"; } 
else if (y < 150) { x = "cat"; }
else if (y < 300) { x = "bar"; } 
else              { x = "baz"; }

Em tarefas como essa, acho que é menos refatorar e mais claro.

Por outro lado, quando estou trabalhando em Ruby, é mais provável que eu use if...else...end porque também é uma expressão.

x =   if (y < 100) then "dog"
    elif (y < 150) then "cat"
    elif (y < 300) then "bar"
    else                "baz"
    end

(embora, admito, para algo tão simples, eu possa usar o operador ternário de qualquer maneira).

O ternário ?: O operador é apenas um equivalente funcional do procedimento if construir. Então, desde que você não esteja usando aninhado ?: Expressões, os argumentos para/contra a representação funcional de qualquer operação se aplica aqui. Mas as operações ternárias de nidificação podem resultar em código que é absolutamente confuso (exercício para o leitor: tente escrever um analisador que lidará com condicionais ternários aninhados e você apreciará sua complexidade).

Mas há muitas situações em que o uso conservador do ?: O operador pode resultar em código que é realmente mais fácil ler do que o contrário. Por exemplo:

int compareTo(Object object) {
    if((isLessThan(object) && reverseOrder) || (isGreaterThan(object) && !reverseOrder)) {
       return 1;
    if((isLessThan(object) && !reverseOrder) || (isGreaterThan(object) && reverseOrder)) {
       return -1;
    else
      return 0;              
}

Agora compare isso com isso:

int compareTo(Object object) {
    if(isLessThan(object))
        return reverseOrder ? 1 : -1;         
    else(isGreaterThan(object))
        return reverseOrder ? -1 : 1;
    else        
       return 0;              
}

Como o código é mais compacto, há menos ruído sintático e, usando o operador ternário criteriosamente (que é apenas em relação ao ordem reversa propriedade) o resultado final não é particularmente conciso.

É uma questão de estilo, realmente; As regras subconscientes que costumo seguir são:

  • Avalie apenas 1 expressão - então foo = (bar > baz) ? true : false, mas não foo = (bar > baz && lotto && someArray.Contains(someValue)) ? true : false
  • Se eu estou usando a lógica de exibição, por exemplo <%= (foo) ? "Yes" : "No" %>
  • Realmente realmente use -o para atribuição; nunca flua a lógica (então nunca (foo) ? FooIsTrue(foo) : FooIsALie(foo) ) A lógica do fluxo em ternário é uma mentira, ignore esse último ponto.

Gosto porque é conciso e elegante para operações de atribuição simples.

Como tantas perguntas de opinião, a resposta é inevitavelmente: depende

Para algo como:

return x ? "Yes" : "No";

Eu acho que é isso Muito de mais conciso (e mais rápido para eu analisar) do que:

if (x) {
    return "Yes";
} else {
    return "No";
}

Agora, se sua expressão condicional for complexa, a operação ternária não é uma boa escolha. Algo como:

x && y && z >= 10 && s.Length == 0 || !foo

não é um bom candidato para o operador ternário.

Como um aparte, se você é um programador C, o GCC realmente tem uma extensão Isso permite que você exclua a parte se verdadeira do ternário, assim:

/* 'y' is a char * */
const char *x = y ? : "Not set";

Que vai definir x para y assumindo y não é NULL. Coisa boa.

Na minha opinião, faz sentido usar o operador ternário nos casos em que uma expressão é necessária.

Em outros casos, parece que o operador ternário diminui a clareza.

Pela medida de complexidade ciclomática, o uso de if As declarações ou o operador ternário são equivalentes. Então, por essa medida, a resposta é não, a complexidade seria exatamente a mesma de antes.

Por outras medidas, como legibilidade, manutenção e seco (não-repetir-se), qualquer opção pode ser melhor que a outra.

Eu o uso com bastante frequência em lugares onde estou restrito a trabalhar em um construtor - por exemplo, os novos constructos .NET 3.5 LINQ a XML - para definir valores padrão quando um parâmetro opcional é nulo.

Exemplo artificial:

var e = new XElement("Something",
    param == null ? new XElement("Value", "Default")
                  : new XElement("Value", param.ToString())
);

ou (obrigado asterite)

var e = new XElement("Something",
    new XElement("Value",
        param == null ? "Default"
                      : param.ToString()
    )
);

Não importa se você usa o operador ternário ou não, garantir que seu código seja legível é a coisa importante. Qualquer construto pode ser tornado ilegível.

Eu uso o operador ternário, onde quer que possa, a menos que isso torne o código extremamente difícil de ler, mas isso geralmente é apenas uma indicação de que meu código pode usar um pouco de refatoração.

Sempre me intriga como algumas pessoas pensam que o operador ternário é um recurso "oculto" ou é um tanto misterioso. É uma das primeiras coisas que aprendi quando começo a programar em C, e acho que não diminui a legibilidade. É uma parte natural da língua.

Eu concordo com Jmulder: não deve ser usado no lugar de um if, mas tem seu lugar para a expressão de retorno ou dentro de uma expressão:

echo "Result: " + n + " meter" + (n != 1 ? "s" : "");
return a == null ? "null" : a;

O primeiro é apenas um exemplo, um melhor apoio do i18N do plural deve ser usado!

(Hack do dia)

#define IF(x) x ?
#define ELSE :

Então você pode fazer se-then-else como expressão:

int b = IF(condition1)    res1
        ELSE IF(condition2)  res2
        ELSE IF(conditions3) res3
        ELSE res4;

Se você estiver usando o operador ternário para uma tarefa condicional simples, acho que está tudo bem. Eu já vi (AB) usou para controlar o fluxo do programa sem sequer fazer uma tarefa, e acho que isso deve ser evitado. Use uma instrução IF nesses casos.

Eu acho que o operador ternário deve ser usado quando necessário. É obviamente uma escolha muito subjetiva, mas acho que uma expressão simples (especialmente como uma expressão de retorno) é muito mais clara que um teste completo. Exemplo em C/C ++:

return (a>0)?a:0;

Comparado com:

if(a>0) return a;
else return 0;

Você também tem o caso em que a solução está entre o operador ternário e a criação de uma função. Por exemplo, em Python:

l = [ i if i > 0 else 0 for i in lst ]

A alternativa é:

def cap(value):
    if value > 0:
        return value
    return 0
l = [ cap(i) for i in lst ]

É necessário o suficiente para que em Python (como exemplo), esse idioma possa ser visto regularmente:

l = [ ((i>0 and [i]) or [0])[0] for i in lst ]

Essa linha usa propriedades dos operadores lógicos no Python: eles são preguiçosos e retorna o último valor calculado se for igual ao estado final.

Eu gosto deles. Não sei por que, mas me sinto muito legal quando uso a expressão ternária.

Eu já vi bestas como (na verdade, era muito pior, pois era IsValiddate e verificou um mês e dia também, mas não me incomodava em tentar lembrar a coisa toda):

isLeapYear =
    ((yyyy % 400) == 0)
    ? 1
    : ((yyyy % 100) == 0)
        ? 0
        : ((yyyy % 4) == 0)
            ? 1
            : 0;

Onde, claramente, uma série de states IF teria sido melhor (embora este ainda seja melhor que a versão macro que eu vi).

Eu não me importo com coisas pequenas como:

reportedAge = (isFemale && (Age >= 21)) ? 21 + (Age - 21) / 3 : Age;

Ou até coisas um pouco complicadas como:

printf ("Deleted %d file%s\n", n, (n == 1) ? "" : "s");

Eu gosto de usar o operador no código de depuração para imprimir valores de erro, para que não precise procurá -los o tempo todo. Normalmente, faço isso para impressões de depuração que não permanecerão quando terminar o desenvolvimento.

int result = do_something();
if( result != 0 )
{
  debug_printf("Error while doing something, code %x (%s)\n", result,
                result == 7 ? "ERROR_YES" :
                result == 8 ? "ERROR_NO" :
                result == 9 ? "ERROR_FILE_NOT_FOUND" :
                "Unknown");
}

Quase nunca uso o operador ternário, porque sempre que o uso, ele sempre me faz pensar muito mais do que preciso mais tarde quando tento mantê -lo.

Eu gosto de evitar a verbosidade, mas quando isso facilita o código, vou optar por verbosidade.

Considerar:

String name = firstName;

if (middleName != null) {
    name += " " + middleName;
}

name += " " + lastName;

Agora, isso é um pouco detalhado, mas acho muito mais legível do que:

String name = firstName + (middleName == null ? "" : " " + middleName)
    + " " + lastName;

ou:

String name = firstName;
name += (middleName == null ? "" : " " + middleName);
name += " " + lastName;

Parece comprimir muita informação em muito pouco espaço, sem deixar claro o que está acontecendo. Toda vez que vejo o operador ternário usado, sempre encontrei uma alternativa que parecia muito mais fácil de ler ... então, novamente, essa é uma opinião extremamente subjetiva; portanto, se você e seus colegas acham muito legível, vá em frente.

Bem, a sintaxe é horrível. Acho o IFS funcional muito útil e geralmente torna o código mais legível.

Eu sugeriria fazer uma macro para torná -la mais legível, mas tenho certeza de que alguém pode criar um caso horrível de borda (como sempre existe com o CPP).

Apenas quando:

$ var = (simples> teste? Simple_result_1: simples_result_2);

BEIJO.

Eu normalmente uso em coisas assim:

before:

if(isheader)
    drawtext(x,y,WHITE,string);
else
    drawtext(x,y,BLUE,string);

after:

    drawtext(x,y,isheader==true?WHITE:BLUE,string);

Como outros apontaram, eles são bons para condições simples e simples. Eu gosto especialmente deles por padrões (como o || e ou uso em javascript e python), por exemplo

int repCount = pRepCountIn ? *pRepCountIn : defaultRepCount;

Outro uso comum é inicializar uma referência no C ++. Como as referências devem ser declaradas e inicializadas na mesma declaração, você não pode usar uma instrução IF.

SomeType& ref = pInput ? *pInput : somethingElse;

Eu trato os operadores ternários muito parecidos com o Goto. Eles têm seu lugar, mas são algo que você geralmente deve evitar para facilitar o entendimento do código.

Recentemente, vi uma variação dos operadores ternários (bem, mais ou menos) que tornam o padrão "()?:" A variante parece ser um modelo de clareza:

var Result = [CaseIfFalse, CaseIfTrue][(boolean expression)]

Ou, para dar um exemplo mais tangível:

var Name = ['Jane', 'John'][Gender == 'm'];

Veja bem, este é JavaScript, então coisas assim podem não ser possíveis em outros idiomas (felizmente).

Para casos simples, eu gosto de usá -lo. Na verdade, é muito mais fácil ler/codificar, por exemplo, como parâmetros para funções ou coisas assim. Também para evitar a nova linha, gosto de manter com todo o meu IF/else.

Neseting seria um grande não-não no meu livro.

Então, retomando, para um único se/senão usarei o operador ternário. Para outros casos, um se/else/else/else (ou switch) regular

Eu gosto do caso especial de Groovy do operador ternário, chamado Operador Elvis :?:

expr ?: default

Este código avalia o Expr se não for nulo e padrão, se for. Tecnicamente, não é realmente um operador ternário, mas está definitivamente relacionado a ele e economiza muito tempo/digitação.

Para tarefas simples, como atribuir um valor diferente, dependendo de uma condição, elas são ótimas. Eu não os usaria quando houver expressões mais longas, dependendo da condição.

Muitas respostas disseram, depende. Acho que, se a comparação ternária não for visível em uma varredura rápida no código, ela não deve ser usada.

Como um problema paralelo, também posso observar que sua própria existência é realmente um pouco de anomoly devido ao fato de que, no C, o teste de comparação é uma declaração. No ícone, o if Construct (como a maior parte do ícone) é na verdade uma expressão. Então você pode fazer coisas como:

x[if y > 5 then 5 else y] := "Y" 

... que eu acho muito mais legível do que um operador de comparação de ternário. :-)

Houve uma discussão recentemente sobre a possibilidade de adicionar o ?: operador para ícone, mas várias pessoas apontaram corretamente que não havia absolutamente nenhuma necessidade por causa do caminho if funciona.

O que significa que, se você pudesse fazer isso em c (ou em qualquer um dos outros idiomas que possuem o operador de ternário), então você não precisaria, de fato, do operador de ternário.

Se você e seus colegas de trabalho entendem o que fazem e não são criados em grupos maciços, acho que tornam o código menos complexo e fácil de ler, porque há simplesmente menos código.

A única vez que acho que os operadores ternários dificultam o código é quando você tem mais de 3 ou 4 em uma linha. A maioria das pessoas não se lembra de que elas têm precedência certa e, quando você tem uma pilha delas, torna a leitura do código um pesadelo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top