Por exemplo, você prefere essa linha única
int median(int a, int b, int c) {
return (a<b) ? (b<c) ? b : (a<c) ? c : a : (a<c) ? a : (b<c) ? c : b;
}
ou uma solução if / else envolvendo várias instruções de retorno?
Quando é ?:
apropriado e quando não é? Deve ser ensinado ou escondido dos iniciantes?
operators
conditions
FredOverflow
fonte
fonte
Respostas:
Não, é uma benção.
Quando é algo tão simples, você não quer perder muitas linhas.
Quando a legibilidade e a clareza do código sofrem e o potencial de erro por atenção insuficiente aumenta, por exemplo, com muitos operadores encadeados, como no seu exemplo.
O teste decisivo é quando você começa a duvidar que seu código seja facilmente legível e mantenível a longo prazo. Então não faça isso.
fonte
myVar = someExpression ? false : true;
(someExpression ? var1 : var2)++
:-)Acho que o operador ternário não aninhado (ou seja, uma declaração em que é usada apenas uma vez) é bom, mas se você estiver aninhando mais de um, fica um pouco difícil de ler.
fonte
Quando é?: Apropriado
e quando não é?
Se você tem alguma chamada lógica ou de função dentro da expressão ternária, está tornando isso horrível de se ver.
fonte
Uma diferença que (acho) ninguém apontou é que o if-else não pode retornar um valor, enquanto o operador ternário pode.
Vindo de F #, às vezes gosto de usar o operador ternário para imitar a correspondência de padrões.
vs
fonte
var res = function() {switch(input) {case 1: return "1"; case 2: return "2"; ...}}()
emular switches como expressões.expression
estatement
mas estou sempre preocupado que eu vou levá-los de forma errada rodada e fazer papel de bobo :)const
variáveis que não podem ser alteradas posteriormente.Um exemplo (IMHO) de um uso válido:
Isso resulta em um código mais legível do que em duas instruções de impressão distintas. Exemplos aninhados dependem: (compreensível? Sim: não)
fonte
Absolutamente não é mau. De fato, é puro , e se-então-outro não é.
Em linguagens funcionais como Haskell, F #, ML etc., são as declarações if-then-else que são consideradas más.
A razão para isso é que qualquer "ação", como uma instrução imperativa se-então-outro, exige que você separe uma declaração variável de sua definição e introduza estado em sua função.
Por exemplo, no seguinte código:
vs.
O primeiro tem duas vantagens além de ser mais curto:
x
é uma constante e, portanto, oferece muito menos chances de introduzir bugs, e pode ser otimizado de maneiras que o segundo nunca poderia ser.x
precisa ser do tipoParity
.De maneira confusa, nas linguagens funcionais, o operador ternário costuma ser chamado se-então-outro. Em Haskell, você pode dizer
x = if n mod 3 == 1 then Odd else Even
.fonte
Essa expressão em particular faz meus olhos doerem; Eu atacaria qualquer desenvolvedor da minha equipe que o usasse porque é impossível de manter.
Os operadores ternários não são maus quando bem utilizados. Eles nem precisam ser linhas simples; Uma longa e bem formatada pode ser muito clara e fácil de entender:
Eu gosto disso melhor do que a cadeia if / then / else equivalente:
Vou reformatá-los em:
se as condições e atribuições permitirem um alinhamento fácil. Ainda assim, prefiro a versão ternária, porque é mais curta e não apresenta tanto ruído nas condições e atribuições.
fonte
O ReSharper no VS.NET às vezes sugere a substituição
if...else
pelo?:
operador.Parece que o ReSharper sugere apenas se as condições / blocos estiverem abaixo de um determinado nível de complexidade, caso contrário, ele permanecerá
if...else
.fonte
Isso pode ser reformatado para ser tão bonito quanto a combinação if / else:
Mas o problema é que não tenho certeza se entendi direito o recuo para representar o que realmente acontecerá. :-)
fonte
if-else
estrutura equivalente . A chave é a formatação.Longe de ser mau, o operador ternário é uma dádiva de Deus.
É mais útil quando você deseja tomar uma decisão em uma expressão aninhada . O exemplo clássico é uma chamada de função:
No seu exemplo particular, o ternário é quase gratuito, pois é a expressão de nível superior sob a
return
. Você pode elevar o condicional ao nível da instrução sem duplicar nada além dareturn
palavra - chave.NB: Nada nunca tornará esse algoritmo específico para mediana fácil de ler.
fonte
printf("I see %d evil construct%s in this program\n", n, "s" unless (n == 1) "s");
Argumentos "malignos" à parte, na minha experiência, encontrei uma alta correlação entre o uso de um programador pelo operador ternário e a probabilidade de toda a sua base de código ser difícil de ler, seguir e manter (se não totalmente não documentada). Se um programador está mais preocupado em salvar algumas linhas de um a dois caracteres do que alguém capaz de entender seu código, qualquer pequena confusão em entender uma declaração ternária é geralmente a ponta do iceberg.
Os operadores ternários atraem números mágicos como s ** t atrai moscas.
Se eu estivesse procurando uma biblioteca de código-fonte aberto para resolver um problema específico, e vi código como os operadores ternários do pôster original em um candidato para essa biblioteca, os sinos de aviso começariam a soar na minha cabeça e eu começaria a pensar em seguir em frente para algum outro projeto para emprestar.
fonte
Aqui está um exemplo de quando é mau:
É confuso e inútil. O compilador pode otimizar a segunda expressão (oldValue = oldValue), mas por que o codificador fez isso em primeiro lugar?
Outro doozy:
Algumas pessoas simplesmente não pretendem ser codificadores ...
Greg diz que a instrução if equivalente é 'barulhenta'. É se você escrever ruidosamente. Mas o mesmo se pode ser escrito como:
O que não é mais barulhento que o ternário. Eu me pergunto se os atalhos ternários; todas as expressões são avaliadas?
fonte
if (x != 0) x = 0;
...Mal? Olha, eles são apenas diferentes.
if
é uma afirmação.(test ? a : b)
é uma expressão. Eles não são a mesma coisa.Expressões existem para expressar valores. Existem instruções para executar ações. Expressões podem aparecer dentro de instruções, mas não vice-versa. Portanto, você pode usar expressões ternárias em outras expressões, como termos em um somatório ou argumentos para um método, e assim por diante. Você não precisa , mas pode, se quiser . Não há nada de errado nisso. Algumas pessoas podem dizer que isso é mau, mas essa é a opinião delas.
Um valor de uma expressão ternária é o fato de lidar com casos verdadeiros e falsos.
if
declarações não.Se você estiver preocupado com a legibilidade, poderá formatá-los de forma legível.
De alguma forma, o "mal" entrou no vocabulário de programação. Eu adoraria saber quem largou primeiro. (Na verdade, eu tenho um suspeito - ele está no MIT.) Prefiro que tenhamos razões objetivas para julgamentos de valor nesse campo, não apenas o gosto das pessoas e os xingamentos.
fonte
Tem um lugar. Já trabalhei em muitas empresas nas quais os níveis de habilidade dos desenvolvedores variam de terrível a assistente. Como o código precisa ser mantido e eu não estarei lá para sempre, tento escrever coisas para que pareçam pertencer a ele (sem olhar para os comentários com minhas iniciais, é extremamente raro você poder veja o código em que trabalhei para ver onde fiz as alterações) e que alguém com menos habilidade do que eu pode mantê-lo.
Embora o operador ternário pareça nitziffic e bem legal, minha experiência é que a linha de código será praticamente impossível de manter. No meu atual empregador, temos produtos que são entregues há quase 20 anos. Eu não usaria esse exemplo em nenhum lugar.
fonte
Não acho que o operador ternário seja mau.
Aqui está uma pegadinha que me deixou perplexo. Eu era um programador C para muitos (10+) e, no final dos anos 90, mudei para a programação de aplicativos baseados na Web. Como programador da Web, logo encontrei o PHP, que também possui um operador ternário. Eu tive um bug em um programa PHP que finalmente rastreiei para uma linha de código com um operador ternário aninhado. Acontece que o operador ternário do PHP associou da esquerda para a direita, mas o operador ternário do PHP (com o qual eu estava acostumado) associa da direita para a esquerda.
fonte
Qualquer coisa que torne seu código mais feio é ruim.
Se você usar ternário para tornar seu código mais limpo, use-o com certeza. Às vezes, no php, é ótimo fazer substituições em linha, por exemplo
Isso salva algumas linhas, e é bem claro, mas seu exemplo precisa de uma formatação pelo menos melhor para ficar claro, e ternário não é realmente bom para várias linhas, então você pode usar if / else.
fonte
Posso dizer isso? Não consigo encontrar esse aplicativo específico da operação ternária evil :
Por favor, tenha piedade, minha reputação já é bastante lamentável.
fonte
Maior vitória: mostra que existe um único alvo de ação.
Existem dois caminhos de código que você pode seguir e o leitor deve ler atentamente para ver quais duas variáveis estão sendo definidas. Nesse caso, é apenas uma variável, mas o leitor precisa ler mais para descobrir isso. Afinal, poderia ter sido isso:
Com o operador ternário, fica claro que apenas uma variável está sendo definida.
No nível mais baixo, é o princípio DRY (não se repita) em sua forma mais básica. Se você pode especificar
$foo
apenas uma vez, faça-o.fonte
Se ... então ... o resto tende a enfatizar a condição e, portanto, desenfatiza as operações condicionais.
o operador ternário é o oposto, tende a ocultar a condição e, portanto, é útil quando a operação que está sendo realizada é mais importante que a própria condição.
Há algumas pequenas diferenças técnicas, em algumas linguagens, que elas não são totalmente intercambiáveis devido a uma ser uma declaração e outra uma expressão, por exemplo, inicializar condicionalmente consts em C ++
fonte
Eu acho que ao desenvolver para um grupo homogêneo de pessoas, não há problema, mas quando você tem que lidar com pessoas que lidam com níveis diferentes, esse tipo de oneliners apenas introduz um outro nível de complexyti no código. Portanto, minha política sobre o assunto é: código claro e não explica, em vez de código curto, e explica 123123 vezes.
Eu não deveria ser ensinado a iniciantes, preferia que eles descobrissem quando a necessidade surgisse; portanto, ela será usada somente quando necessário e não sempre que você precisar.
fonte
Na IMO, o próprio operador não é ruim, mas a sintaxe usada em C (e C ++) é excessivamente concisa. OMI, Algol 60 fez melhor, então algo assim:
ficaria mais parecido com este (mas mantendo a sintaxe do tipo C em geral):
Mesmo com isso, o aninhamento excessivamente profundo pode levar a problemas de legibilidade, mas pelo menos A) qualquer pessoa que já tenha feito programação pode descobrir um processo simples e B) as pessoas que entendem isso podem lidar com o aninhamento consideravelmente mais profundo com bastante facilidade. OTOH, eu também observaria que no LISP (por exemplo) a
cond
é quase como uma declaração ternária - não um conjunto de instruções, mas uma única expressão gera um valor (então, novamente, a maior parte do LISP é assim .. .)fonte
A = (x==y) ? B : C
Uma loja que escreve regularmente métodos de 600 a 1200 linhas não deve me dizer que um ternário é "difícil de entender". Qualquer loja que permita regularmente cinco condições para avaliar uma ramificação de código não deve me dizer que as condições resumidas concretamente em um ternário são "difíceis de ler".
fonte
Quando é?: Apropriado e quando não é?
Deve ser ensinado ou escondido dos iniciantes?
Não importa, mas não deve ser intencionalmente oculto, pois não é muito complexo para um "iniciante" aprender.
fonte
No seu exemplo:
é muito simples de ler e óbvio. A variável entre <<é o valor de retorno.
Atualizar
mesmo, mas menos linhas de código. Ainda simples, eu acho.
fonte
Também é necessário para const
fonte
const
é assim em certas línguas. Em C #const
deve sempre ser o valor conhecido do tempo de compilação. o que significa queconst int nLegs = isChicken ? 2: 4 ;
não vai funcionar, masconst int nLegs = true ? 2: 4 ;
vai