Domanda

Personalmente sono un sostenitore dell'operatore ternario:() ?:;Mi rendo conto che ha il suo posto, ma mi sono imbattuto in molti programmatori che sono completamente contro di usarla, e alcuni che utilizzano troppo spesso.

Quali sono i tuoi sentimenti su di esso?La cosa interessante di codice hai visto usando?

È stato utile?

Soluzione

Usalo solo per espressioni semplici :

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

Non concatenare o nidificare operatori ternari poiché è difficile da leggere e confondere:

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

Inoltre, quando si utilizza l'operatore ternario, considerare la formattazione del codice in modo da migliorare la leggibilità:

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

Altri suggerimenti

Rende il debug leggermente più difficile poiché non è possibile posizionare punti di interruzione su ciascuna delle espressioni secondarie. Lo uso raramente.

Li adoro, specialmente in linguaggi di sicurezza.

Non vedo come questo:

int count = (condition) ? 1 : 0;

è più difficile di così:

int count;

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

modifica -

Direi che gli operatori ternari rendono tutto meno complesso e più pulito dell'alternativa.

Incatenato con cui sto bene - nidificato, non così tanto.

Tendo a usarli di più in C semplicemente b / c sono un'istruzione if che ha valore, quindi riduce le ripetizioni o le variabili non necessarie:

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

anziché

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

In incarichi come questo, trovo che sia minore il refactoring e più chiaro.

Quando invece lavoro in ruby, ho più probabilità di usare if...else...end perché è anche un'espressione.

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

(anche se, devo ammetterlo, per qualcosa di così semplice, potrei comunque usare l'operatore ternario).

L'operatore Ternario ?: è semplicemente un equivalente funzionale del costrutto if procedurale. Pertanto, fintanto che non si utilizzano espressioni nidificate <=>, qui si applicano gli argomenti a favore / contro la rappresentazione funzionale di qualsiasi operazione. Ma l'annidamento delle operazioni ternarie può comportare un codice decisamente confuso (esercizio per il lettore: prova a scrivere un parser che gestirà i condizionali ternari annidati e ne apprezzerai la complessità).

Ma ci sono molte situazioni in cui un uso prudente dell'operatore <=> può risultare in codice che è più facile da leggere che altrimenti. Ad esempio:

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;              
}

Ora confrontalo con questo:

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

Dato che il codice è più compatto, c'è meno rumore sintattico e usando l'operatore ternario con giudizio (cioè solo in relazione alla proprietà reverseOrder ) il risultato finale non è particolarmente conciso.

È davvero una questione di stile; le regole inconsce che tendo a seguire sono:

  • Valuta solo 1 espressione, quindi foo = (bar > baz) ? true : false, ma NON foo = (bar > baz && lotto && someArray.Contains(someValue)) ? true : false
  • Se lo sto usando per la logica di visualizzazione, ad es. <%= (foo) ? "Yes" : "No" %>
  • Lo usi davvero solo per il compito; logica del flusso mai (quindi mai (foo) ? FooIsTrue(foo) : FooIsALie(foo)) la logica del flusso in ternario è essa stessa una bugia, ignora l'ultimo punto.

Mi piace perché è conciso ed elegante per semplici operazioni di assegnazione.

Come tante domande d'opinione, la risposta è inevitabilmente: dipende

Per qualcosa del tipo:

return x ? "Yes" : "No";

Penso che sia molto più conciso (e più veloce per me analizzare) di:

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

Ora se la tua espressione condizionale è complessa, l'operazione ternaria non è una buona scelta. Qualcosa del tipo:

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

non è un buon candidato per l'operatore ternario.

A parte questo, se sei un programmatore C, GCC ha effettivamente un'estensione che ti consente di escludere la porzione if-true del ternario, in questo modo:

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

Che imposterà x su y supponendo che NULL non sia <=>. Roba buona.

Nella mia mente, ha senso usare l'operatore ternario solo nei casi in cui è necessaria un'espressione.

In altri casi, sembra che l'operatore ternario riduca la chiarezza.

Con la misura di complessità ciclomatica , l'uso di if istruzioni o l'operatore ternario sono equivalenti. Quindi, con questa misura, la risposta è no , la complessità sarebbe esattamente la stessa di prima.

Con altre misure come la leggibilità, la manutenibilità e il DRY (Don't Repeat-Yourself), entrambe le scelte possono rivelarsi migliori dell'altra.

Lo uso abbastanza spesso in luoghi in cui sono costretto a lavorare in un costruttore - ad esempio, i nuovi costrutti .NET 3.5 LINQ to XML - per definire valori predefiniti quando un parametro opzionale è null.

Esempio contrastato:

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

o (grazie asterite)

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

Non importa se usi l'operatore ternario o meno, assicurarti che il tuo codice sia leggibile è la cosa importante. Qualsiasi costrutto può essere reso illeggibile.

Uso l'operatore ternario ogni volta che posso, a meno che non renda il codice estremamente difficile da leggere, ma di solito è solo un'indicazione che il mio codice potrebbe usare un piccolo refactoring.

Mi sconcerta sempre il modo in cui alcune persone pensano che l'operatore ternario sia un " nascosto " caratteristica o è in qualche modo misterioso. È una delle prime cose che ho imparato quando ho iniziato a programmare in C e non credo che diminuisca affatto la leggibilità. È una parte naturale della lingua.

Sono d'accordo con jmulder: non dovrebbe essere usato al posto di un if, ma ha il suo posto per un'espressione di ritorno o dentro un'espressione:

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

Il primo è solo un esempio, dovrebbe essere usato un supporto i18n migliore del plurale!

(Hack del giorno)

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

Quindi puoi fare if-then-else come espressione:

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

Se stai usando l'operatore ternario per un semplice incarico condizionale, penso che vada bene. L'ho visto (ab) usato per controllare il flusso del programma senza nemmeno fare un compito, e penso che dovrebbe essere evitato. Utilizzare un'istruzione if in questi casi.

Penso che l'operatore ternario debba essere usato quando necessario. È ovviamente una scelta molto soggettiva, ma trovo che un'espressione semplice (specialmente come espressione di ritorno) sia molto più chiara di un test completo. Esempio in C / C ++:

return (a>0)?a:0;

Rispetto a:

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

Hai anche il caso in cui la soluzione è tra l'operatore ternario e la creazione di una funzione. Ad esempio in Python:

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

L'alternativa è:

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

È necessario abbastanza che in Python (come esempio), un tale linguaggio possa essere visto regolarmente:

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

questa linea usa le proprietà degli operatori logici in Python: sono pigri e restituiscono l'ultimo valore calcolato se è uguale allo stato finale.

Mi piacciono. Non so perché, ma mi sento molto bene quando uso l'espressione ternaria.

Ho visto queste bestie come (in realtà è stato molto di peggio, poiché è stato isValidDate e controllato il mese e il giorno, ma non potevo essere disturbato cercando di ricordare il tutto):

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

dove, chiaramente, di una serie di if-istruzioni sarebbe stato meglio (anche se questo è ancora meglio rispetto alla versione macro, una volta ho visto).

Non mi dispiace per le piccole cose come:

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

anche un po ' di cose complicate come:

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

Mi piace usare l'operatore nel codice di debug per stampare i valori di errore, quindi non devo cercarli sempre. Di solito lo faccio per le stampe di debug che non rimarranno una volta terminato lo sviluppo.

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");
}

Non uso quasi mai l'operatore ternario perché ogni volta che lo uso, mi fa sempre pensare molto di più di quanto non debba fare in seguito quando provo a mantenerlo.

Mi piace evitare la verbosità, ma quando renderà il codice molto più facile da raccogliere, proverò la verbosità.

Si consideri:

String name = firstName;

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

name += " " + lastName;

Ora, è un po 'prolisso, ma lo trovo molto più leggibile di:

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

o

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

Sembra semplicemente comprimere troppe informazioni in troppo poco spazio, senza chiarire cosa sta succedendo. Ogni volta che vedo un operatore ternario usato, ho sempre trovato un'alternativa che sembrava molto più facile da leggere ... poi di nuovo, è un'opinione estremamente soggettiva, quindi se tu e i tuoi colleghi trovate il ternario molto leggibile, provatelo.

Beh, la sintassi è orribile. Trovo molto utile se funzionale, e spesso rende il codice più leggibile.

Suggerirei di creare una macro per renderla più leggibile, ma sono sicuro che qualcuno può inventare un orribile caso limite (come sempre accade con CPP).

Solo quando:

$ var = (semplice > test? simple_result_1: simple_result_2);

BACIO.

Di solito lo uso in cose come queste:

before:

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

after:

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

Come altri hanno sottolineato, sono carini per brevi e semplici condizioni. Mi piacciono particolarmente per i valori predefiniti (un po 'come l'uso || e o in javascript e python), ad esempio

int repCount = pRepCountIn ? *pRepCountIn : defaultRepCount;

Un altro uso comune è inizializzare un riferimento in C ++. Poiché i riferimenti devono essere dichiarati e inizializzati nella stessa istruzione, non è possibile utilizzare un'istruzione if.

SomeType& ref = pInput ? *pInput : somethingElse;

Tratto gli operatori ternari come GOTO. Hanno il loro posto, ma sono qualcosa che di solito dovresti evitare per rendere il codice più facile da capire.

Di recente ho visto una variazione sugli operatori ternari (beh, una specie di) che rendono lo standard " ()? &: Quot; la variante sembra essere un esempio di chiarezza:

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

oppure, per fare un esempio più tangibile:

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

Intendiamoci, questo è Javascript, quindi cose del genere potrebbero non essere possibili in altre lingue (per fortuna).

Per casi semplici, mi piace usarlo. In realtà è molto più facile leggere / codificare ad esempio come parametri per funzioni o cose del genere. Anche per evitare la nuova linea mi piace mantenere tutto il mio if / else.

Annullare sarebbe un grande NO-NO nel mio libro.

Quindi, riprendendo, per un singolo if / else userò l'operatore ternario. Per altri casi un normale if / else if / else (o switch)

Mi piace il caso speciale di Groovy dell'operatore ternario, chiamato operatore Elvis:?:

expr ?: default

Questo codice viene valutato in expr se non è null e, se lo è, è predefinito. Tecnicamente non è davvero un operatore ternario, ma è sicuramente correlato ad esso e consente di risparmiare molto tempo / digitazione.

Per compiti semplici come assegnare un valore diverso a seconda di una condizione, sono grandi. Non li userei quando ci sono espressioni più lunghe a seconda della condizione.

Molte risposte hanno detto, dipende . Trovo che se il confronto ternario non è visibile in una scansione veloce del codice, non dovrebbe essere usato.

Come problema secondario, potrei anche notare che la sua stessa esistenza è in realtà un po 'un'anomalia a causa del fatto che in C, i test di confronto sono un'affermazione. In Icon, il costrutto if (come la maggior parte di Icon) è in realtà un'espressione. Quindi puoi fare cose come:

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

... che trovo molto più leggibile di un operatore di confronto ternery. : -)

Di recente si è discusso della possibilità di aggiungere l'operatore ?: a Icon, ma diverse persone hanno correttamente sottolineato che non era assolutamente necessario a causa del modo in cui <=> funziona.

Il che significa che se potessi farlo in C (o in una qualsiasi delle altre lingue che hanno l'operatore ternery), in realtà non avresti affatto bisogno dell'operatore ternery.

Se tu e i tuoi colleghi capite cosa fanno e non vengono creati in gruppi di grandi dimensioni, penso che rendano il codice meno complesso e più facile da leggere perché c'è semplicemente meno codice.

L'unica volta in cui penso che gli operatori ternari rendano il codice più difficile da capire è quando hai più di 3 o 4 in una riga. La maggior parte delle persone non ricorda che hanno la giusta precedenza basata e quando ne hai una pila rende la lettura del codice un incubo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top