Lo sviluppatore insiste se le affermazioni non dovrebbero avere condizioni negate e dovrebbero sempre avere un altro blocco

161

Ho un conoscente, uno sviluppatore più esperto di me. Stavamo parlando di pratiche di programmazione e sono rimasto sconcertato dal suo approccio sulle dichiarazioni "se". Insiste su alcune pratiche riguardanti le affermazioni che trovo piuttosto strane.

In primo luogo , un'istruzione if dovrebbe essere seguita da un'altra istruzione, indipendentemente dal fatto che ci sia qualcosa da aggiungere o meno. Il che porta al codice simile a questo:

if(condition) 
{
    doStuff();
    return whatever;
}
else
{
}

In secondo luogo , è meglio testare i valori veri anziché i falsi. Ciò significa che è meglio testare una variabile "doorClosed" anziché una variabile "! DoorOpened"

Il suo argomento è che rende più chiaro ciò che sta facendo il codice.

Il che mi confonde un po ', poiché una combinazione di queste due regole può portarlo a scrivere questo tipo di codice se vuole fare qualcosa quando la condizione non è soddisfatta.

if(condition)
{
}
else
{
    doStuff();
    return whatever;
}

Il mio sentimento a riguardo è che è davvero molto brutto e / o che il miglioramento della qualità, se presente, è trascurabile. Ma da junior, sono incline a dubitare del mio istinto.

Quindi le mie domande sono: È una buona / cattiva / "non importa" la pratica? È una pratica comune?

    
posta Patsuan 08.06.2017 - 15:35
fonte

15 risposte

177

Blocco esplicito else

La prima regola semplicemente inquina il codice e non lo rende né più leggibile né meno soggetto a errori. L'obiettivo del tuo collega, suppongo, è di essere esplicito, dimostrando che lo sviluppatore era pienamente consapevole che la condizione poteva essere valutata a false . Sebbene sia una buona cosa essere espliciti, tale esplicitazione non dovrebbe comportare il costo di tre righe di codice aggiuntive .

Non accenno nemmeno al fatto che un'istruzione if non sia necessariamente seguita da un else o da niente: potrebbe essere seguito anche da uno o più elif s.

La presenza dell'istruzione return peggiora le cose. Anche se hai effettivamente il codice da eseguire all'interno del blocco else , sarebbe più leggibile farlo in questo modo:

if (something)
{
    doStuff();
    return whatever;
}

doOtherThings();
return somethingElse;

In questo modo il codice prende due righe in meno e unindentifica il blocco else . Le clausole di salvaguardia riguardano tutto questo.

Notate, tuttavia, che la tecnica del vostro collega potrebbe parzialmente risolvere un modello molto brutto di blocchi condizionali impilati senza spazi:

if (something)
{
}
if (other)
{
}
else
{
}

Nel codice precedente, la mancanza di un'interruzione di linea sensata dopo il primo blocco if rende molto facile interpretare erroneamente il codice. Tuttavia, mentre la regola del collega renderebbe più difficile interpretare erroneamente il codice, una soluzione più semplice sarebbe semplicemente aggiungere una nuova riga.

Test per true , non per false

La seconda regola potrebbe avere un senso, ma non nella sua forma attuale.

Non è falso che il test per una porta chiusa sia più intuitivo del test per una porta non aperta . Le negazioni, e in particolare le negazioni annidate, sono solitamente difficili da capire:

if (!this.IsMaster || (!this.Ready && !this.CanWrite))

Per risolvere questo problema, invece di aggiungere blocchi vuoti, crea proprietà aggiuntive, se pertinenti, o variabili locali .

La condizione sopra potrebbe essere resa facilmente leggibile:

if (this.IsSlave || (this.Synchronizing && this.ReadOnly))
    
risposta data 08.06.2017 - 15:46
fonte
62

Riguardo alla prima regola, questo è un esempio di digitazione inutile. Non solo ci vuole più tempo per digitare, causerà enormi quantità di confusione a chiunque legga il codice. Se il codice non è necessario, non scriverlo. Ciò si estenderebbe anche al fatto di non avere un% pop_cos% popolato nel tuo caso quando il codice ritorna dal blocco else :

if(condition) 
{
    doStuff();
    return whatever;
}

doSomethingElse(); // no else needed
return somethingelse;

Riguardo al secondo punto, è bene evitare nomi booleani che contengono un negativo:

bool doorNotOpen = false; // a double negative is hard to reason
bool doorClosed = false; // this is much clearer

Tuttavia, estendere questo per non testare di nuovo un negativo, come si fa notare, porta a una digitazione più inutile. Quanto segue è molto più chiaro di un blocco if vuoto:

if(!condition)
{
    doStuff();
    return whatever;
}
    
risposta data 08.06.2017 - 15:54
fonte
44

1. Un argomento a favore di dichiarazioni else vuote.

Spesso uso (e sostengo) qualcosa di simile a quel primo costrutto, un altro vuoto. Segnala ai lettori del codice (strumenti di analisi sia umani che automatizzati) che il programmatore ha messo in discussione la situazione. Le dichiarazioni di else mancanti che avrebbero dovuto essere presenti hanno ucciso persone, fatto crollare veicoli e costato milioni di dollari. MISRA-C, ad esempio, richiede almeno un commento che dice che l'ultimo finale mancante è intenzionale in una sequenza if (condition_1) {do_this;} else if (condition_2) {do_that;} ... else if (condition_n) {do_something_else;} . Altri standard di alta affidabilità vanno anche oltre: con alcune eccezioni, le altre dichiarazioni mancanti sono proibite.

Un'eccezione è un semplice commento, qualcosa sulla falsariga di /* Else not required */ . Ciò indica lo stesso intento della terza linea vuota. Un'altra eccezione in cui quel vuoto non è necessario è il punto in cui è palesemente ovvio per entrambi i lettori del codice e per gli strumenti di analisi automatizzati che rendono inutile il superfluo. Ad esempio, if (condition) { do_stuff; return; } Allo stesso modo, un altro vuoto non è necessario nel caso di throw something o goto some_label 1 al posto di return .

2. Un argomento per preferire if (condition) su if (!condition) .

Questo è un elemento dei fattori umani. La complessa logica booleana fa inciampare molte persone. Anche un programmatore esperto dovrà pensare a if (!(complex || (boolean && condition))) do_that; else do_this; . Come minimo, riscrivilo come if (complex || (boolean && condition)) do_this; else do_that; .

3. Questo non significa che si dovrebbero preferire le dichiarazioni then vuote.

La seconda sezione dice "preferisci" piuttosto che "tu". È una linea guida piuttosto che una regola. La ragione per cui le linee guida preferiscono condizioni di if positive è che il codice dovrebbe essere chiaro ed evidente. Una clausola vuota allora (ad esempio if (condition) ; else do_something; ) viola questo. È una programmazione offuscata, che fa sì che anche i programmatori più esperti eseguano il backup e rileggano la condizione if nella sua forma negata. Quindi scrivilo prima nella forma negata e ometti la dichiarazione else (o hai un altro vuoto o un commento in tal senso se sei obbligato a farlo).


1 Ho scritto che allora le clausole che terminano con return , throw o goto non richiedono un altro vuoto. È ovvio che la clausola else non è necessaria. Ma per quanto riguarda goto ? Per inciso, le regole di programmazione critiche per la sicurezza a volte non consentono il ritorno anticipato e quasi sempre non consentono eccezioni. Tuttavia, ammettono goto in un formato limitato (ad esempio goto cleanup1; ). Questo uso limitato di goto è la pratica preferita in alcuni luoghi. Il kernel di Linux, per esempio, è pieno di tali dichiarazioni goto .

    
risposta data 09.06.2017 - 12:55
fonte
30

Uso un ramo else vuoto (e talvolta un if branch vuoto) in casi molto rari: quando è ovvio che sia la parte if che la parte else devono essere gestite in qualche modo, ma per qualche motivo non banale il caso può essere gestito senza fare nulla E quindi chiunque leggesse il codice con l'altra azione necessaria sospetterebbe immediatamente che qualcosa manchi e sprechi il loro tempo.

if (condition) {
    // No action needed because ...
} else {
    do_else_action()
}

if (condition) {
    do_if_action()
} else {
    // No action needed because ...
}

Ma non:

if (condition) {
    do_if_action()
} else {
    // I was told that an if always should have an else ...
}
    
risposta data 09.06.2017 - 21:06
fonte
23

A parità di condizioni, preferisci la brevità.

Ciò che non scrivi, nessuno deve leggere e capire.

Anche se essere espliciti può essere utile, è solo il caso se rende evidente senza indebita verbosità che ciò che hai scritto è davvero ciò che volevi scrivere.

Quindi, evita i rami vuoti, non solo sono inutili ma anche non comuni e quindi creano confusione.

Inoltre, evita di scrivere un altro ramo se esci direttamente dal if-branch.

Un'utile applicazione di explicitness potrebbe mettere un commento ogni volta che cadi nei casi di switch // FALLTHRU , e usando un commento o un blocco vuoto in cui hai bisogno di un'istruzione vuota for(a;b;c) /**/; .

    
risposta data 08.06.2017 - 20:35
fonte
6

Non c'è una regola ferrea sulle condizioni positive o negative per una dichiarazione di IF, non a mia conoscenza. Personalmente preferisco la codifica per un caso positivo piuttosto che un negativo, dove applicabile. Certamente non lo farò, se mi induce a creare un blocco IF vuoto, seguito da un ELSE pieno di logica. Se si presentasse una situazione del genere, ci vorrebbero comunque 3 secondi per refactarlo di nuovo a test per un caso positivo.

Ciò che davvero non mi piace dei tuoi esempi, però, è lo spazio verticale completamente inutile occupato dall'ELSE vuoto. Non c'è assolutamente nessuna ragione per farlo. Non aggiunge nulla alla logica, non aiuta a documentare cosa sta facendo il codice e non aumenta affatto la leggibilità. In effetti, direi che lo spazio verticale aggiunto potrebbe diminuire di leggibilità

    
risposta data 08.06.2017 - 15:50
fonte
5

Blocco esplicito else

Non sono d'accordo con questo come una dichiarazione coperta che copre tutte le dichiarazioni if , ma ci sono momenti in cui l'aggiunta di un blocco else per abitudine è una buona cosa.

Un'istruzione if , a mio parere, copre in realtà due funzioni distinte.

Se dovessimo fare qualcosa, fallo qui.

Cose del genere ovviamente non richiedono una parte else .

    if (customer.hasCataracts()) {
        appointmentSuggestions.add(new CataractAppointment(customer));
    }
    if (customer.isDiabetic()) {
        customer.assignNurse(DiabeticNurses.pickBestFor(customer));
    }

e in alcuni casi insistere sull'aggiunta di else potrebbe indurre in errore.

    if (k > n) {
        return BigInteger.ZERO;
    }
    if (k <= 0 || k == n) {
        return BigInteger.ONE;
    }

è non uguale a

    if (k > n) {
        return BigInteger.ZERO;
    } else {
        if (k <= 0 || k == n) {
            return BigInteger.ONE;
        }
    }

anche se è funzionalmente lo stesso. Scrivere il primo if con una else vuota può portare al secondo risultato che è inutilmente brutto.

Se stiamo verificando uno stato specifico, è spesso una buona idea aggiungere un else vuoto solo per ricordarti di coprire quell'eventualità

        // Count wins/losses.
        if (doors[firstChoice] == Prize.Car) {
            // We would have won without switching!
            winWhenNotSwitched += 1;
        } else {
            // We win if we switched to the car!
            if (doors[secondChoice] == Prize.Car) {
                // We picked right!
                winWhenSwitched += 1;
            } else {
                // Bad choice.
                lost += 1;
            }
        }

Ricorda che queste regole si applicano solo quando scrivi nuovo codice . IMHO Le clausole else vuote devono essere rimosse prima del check-in.

Test per true , non per false

Anche in questo caso si tratta di un buon consiglio a livello generale, ma in molti casi ciò rende il codice inutilmente complesso e meno leggibile.

Anche se codice come

    if(!customer.canBuyAlcohol()) {
        // ...
    }

è stridente per il lettore, ma lo rende

    if(customer.canBuyAlcohol()) {
        // Do nothing.
    } else {
        // ...
    }

è almeno altrettanto brutto, se non peggio.

Ho codificato in BCPL molti anni fa e in quel linguaggio c'è una clausola IF e una clausola UNLESS in modo da poter codificare molto più facilmente come:

    unless(customer.canBuyAlcohol()) {
        // ...
    }

che è significativamente migliore, ma non è ancora perfetto.

Il mio processo personale

In genere, quando scrivo il codice nuovo aggiungo spesso un blocco else vuoto a un'istruzione if solo per ricordarmi che non ho ancora coperto quell'eventualità. Questo mi aiuta a evitare la trappola DFS e assicura che quando riesame il codice, noto che c'è ancora molto da fare. Tuttavia, di solito aggiungo un commento di TODO per tenere traccia.

  if (returnVal == JFileChooser.APPROVE_OPTION) {
    handleFileChosen();
  } else {
    // TODO: Handle case where they pressed Cancel.
  }

Trovo che generalmente io uso else raramente nel mio codice in quanto spesso può indicare un odore di codice.

    
risposta data 09.06.2017 - 11:31
fonte
1

Per il primo punto, ho usato un linguaggio che ha forzato l'uso delle istruzioni IF in questo modo (in Opal, il linguaggio dietro uno scraper dello schermo del mainframe per mettere un front-end della GUI sui sistemi mainframe) e con una sola riga per IF e ELSE. Non è stata un'esperienza piacevole!

Mi aspetto che un compilatore possa ottimizzare tali clausole ELSE aggiuntive. Ma per il codice live non aggiunge nulla (in fase di sviluppo può essere un utile indicatore per un ulteriore codice).

Una volta che uso qualcosa di simile a queste clausole extra si verifica quando si utilizza l'elaborazione CASE / WHEN. Aggiungo sempre una clausola predefinita anche se è vuota. Questa è un'abitudine a lungo termine da parte di linguaggi che commetterà errori se tale clausola non viene utilizzata, e costringe a pensare se le cose dovrebbero davvero passare.

Molto tempo fa mainframe (ad esempio, PL / 1 e COBOL) praticava che era accettato che i controlli negativi erano meno efficienti. Questo potrebbe spiegare il secondo punto, anche se in questi giorni ci sono risparmi di efficienza molto più importanti che vengono ignorati come micro ottimizzazioni.

La logica negativa tende ad essere meno leggibile, sebbene non così tanto su una dichiarazione IF semplice.

    
risposta data 09.06.2017 - 12:50
fonte
1

Vorrei prendere in considerazione la maggior parte delle risposte che i blocchi else vuoti sono praticamente sempre uno spreco dannoso di inchiostro elettronico. Non aggiungerli a meno che tu non abbia una buona ragione per farlo, nel qual caso il blocco vuoto non dovrebbe essere vuoto, dovrebbe contenere un commento che spieghi perché è lì.

Il problema dell'eliminazione dei negativi merita tuttavia una maggiore attenzione: in genere, ogni volta che è necessario utilizzare un valore booleano, è necessario utilizzare alcuni blocchi di codice quando è impostato e alcuni altri blocchi da utilizzare quando non è impostato. In quanto tale, se si applica una regola senza negazione, si applica o la presenza di istruzioni if() {} else {...} (con un blocco if vuoto!) O si crea un secondo booleano per ciascun valore booleano che contiene il valore negato. Entrambe le opzioni sono sbagliate, poiché confondono i tuoi lettori.

Un criterio utile è questo: non usare mai un modulo negato nel nome di un booleano ed esprimere la negazione come un singolo ! . Una frase come if(!doorLocked) è perfettamente chiara, una dichiarazione come if(!doorUnlocked) knots brains. Il tipo di espressione successivo è la cosa che devi evitare a tutti i costi, non la presenza di un singolo ! in una condizione if() .

    
risposta data 11.06.2017 - 03:26
fonte
0

Direi che è decisamente una cattiva pratica. Aggiungere altre istruzioni aggiungerà al codice una serie di linee inutili che non fanno nulla e ne rendono ancora più difficile la lettura.

    
risposta data 08.06.2017 - 15:49
fonte
0

C'è un punto nel considerare l'argomento "sempre avere un'altra clausola" che non ho visto in nessun'altra risposta: può avere senso in uno stile di programmazione funzionale. Sort of.

In uno stile di programmazione funzionale, ti occupi di espressioni piuttosto che di affermazioni. Quindi ogni blocco di codice ha un valore di ritorno, inclusa un'espressione if-then-else . Ciò, tuttavia, preclude un blocco else vuoto. Lasciatemi fare un esempio:

var even = if (n % 2 == 0) {
  return "even";
} else {
  return "odd";
}

Ora, nelle lingue con stile C o sintassi ispirata allo stile C (come Java, C # e JavaScript, solo per nominarne alcuni) questo sembra strano. Tuttavia sembra molto più familiare quando scritto in quanto tale:

var even = (n % 2 == 0) ? "even" : "odd";

Lasciando il ramo else vuoto qui causerebbe un valore non definito - nella maggior parte dei casi, non quello che vogliamo essere un caso valido quando si programmano le funzionalità. Lo stesso con lasciandolo completamente fuori. Tuttavia, quando stai programmando in modo iterativo, ho impostato pochissime ragioni per avere sempre un blocco else .

    
risposta data 11.06.2017 - 22:52
fonte
0

...an if statement should be followed by an else statement, whether there is something to put into it or not.

Non concordo che if (a) { } else { b(); } debba essere riscritto come if (!a) { b(); } e if (a) { b(); } else { } deve essere riscritto come if (a) { b(); } .

Tuttavia, vale la pena sottolineare che raramente ho un ramo vuoto. Questo perché normalmente registro che sono entrato nel ramo altrimenti vuoto. In questo modo posso sviluppare esclusivamente messaggi di log. Uso raramente un debugger. Negli ambienti di produzione non si ottiene un debugger; è bello essere in grado di risolvere i problemi di produzione con gli stessi strumenti che si utilizzano per lo sviluppo.

Secondly, it's better to test for true values rather than false. That means that it's better to test a 'doorClosed' variable instead of a '!doorOpened' variable

Ho sentimenti contrastanti su questo. Uno svantaggio di avere doorClosed e doorOpened è che potenzialmente raddoppia il numero di parole / termini di cui devi essere a conoscenza. Un altro svantaggio è nel tempo che il significato di doorClosed e doorOpened può cambiare (altri sviluppatori arrivano dopo di te) e potresti finire con due proprietà che non sono più negazioni precise l'una dell'altra. Invece di evitare le negazioni, apprezzo l'adattamento della lingua del codice (nomi di classi, nomi di variabili, ecc.) Al vocabolario degli utenti aziendali e ai requisiti che mi vengono dati. Non vorrei creare un termine completamente nuovo per evitare un ! se quel termine ha solo un significato per uno sviluppatore che gli utenti aziendali non capiranno. Voglio che gli sviluppatori parlino la stessa lingua degli utenti e delle persone che scrivono i requisiti. Ora, se nuovi termini semplificano il modello, allora è importante, ma dovrebbe essere gestito prima che i requisiti siano finalizzati, non dopo. Lo sviluppo dovrebbe gestire questo problema prima che inizino a programmare.

I am prone to doubt my instinct.

È bello continuare a mettere in discussione te stesso.

Is it a good/bad/"doesn't matter" practice?

In una certa misura molto non importa. Ottieni il tuo codice rivisto e adatto al tuo team. Di solito è la cosa giusta da fare. Se tutti i membri del team desiderano codificare in un determinato modo, probabilmente è meglio farlo in quel modo (cambiando 1 persona -  te stesso - prende meno punti storia di cambiare un gruppo di persone).

Is it common practice?

Non ricordo di aver mai visto un ramo vuoto. Vedo però persone che aggiungono proprietà per evitare le negazioni.

    
risposta data 12.06.2017 - 18:06
fonte
0

Vado solo ad affrontare la seconda parte della domanda e questo viene dal mio punto di vista di lavorare in sistemi industriali e manipolare dispositivi nel mondo reale.

Tuttavia questo è in qualche modo un commento esteso piuttosto che una risposta.

Quando viene indicato

Secondly, it's better to test for true values rather than false. That means that it's better to test a 'doorClosed' variable instead of a '!doorOpened' variable

His argument is that it makes clearer what the code is doing.

Dal mio punto di vista l'ipotesi è che qui lo stato della porta sia uno stato binario quando in realtà è almeno uno stato ternario:

  1. La porta è aperta.
  2. La porta non è né completamente aperta né completamente chiusa.
  3. La porta è chiusa.

Quindi, a seconda di dove si trova un singolo sensore digitale binario, puoi solo ipotizzare uno dei due concetti:

  1. Se il sensore si trova sul lato aperto della porta: la porta è aperta o non aperta
  2. Se il sensore si trova sul lato chiuso della porta: la porta è chiusa o non chiusa.

E non puoi scambiare questi concetti con l'uso di una negazione binaria. Pertanto, doorClosed e !doorOpened non sono probabilmente sinonimi e qualsiasi tentativo di fingere che siano sinonimi è un pensiero erroneo che presuppone una maggiore conoscenza dello stato del sistema rispetto all'esistenza effettiva.

Tornando alla tua domanda, sosterrei la verbosità che corrisponde all'origine delle informazioni rappresentate dalla variabile. Quindi se l'informazione è derivata dal lato chiuso della porta, allora vai con doorClosed ecc. Ciò può implicare l'utilizzo di doorClosed o !doorClosed come necessario in varie dichiarazioni come richiesto, con conseguente potenziale confusione con l'uso del negazione. Ma ciò che non fa è implicitamente propagare ipotesi sullo stato del sistema.

A fini di discussione per il lavoro che svolgo, la quantità di informazioni che ho a disposizione sullo stato del sistema dipende dalla funzionalità richiesta dal sistema generale stesso.

A volte ho solo bisogno di sapere se la porta è chiusa o non chiusa. In tal caso sarà sufficiente un solo sensore binario. Ma altre volte ho bisogno di sapere che la porta è aperta, chiusa o in transizione. In questi casi ci sarebbero due sensori binari (ad ogni estremo del movimento della porta - con controllo degli errori contro la contemporanea apertura e chiusura della porta) o ci sarebbe un sensore analogico che misura come "aprire" la porta.

Un esempio del primo sarebbe la porta di un forno a microonde. Si abilita il funzionamento del forno in base alla porta chiusa o non chiusa. Non ti interessa come è aperta la porta.

Un esempio del secondo sarebbe un semplice attuatore motorizzato. Si inibisce l'avanzamento del motore in avanti quando l'attuatore è completamente fuori. E inibisci l'azionamento del motore in retromarcia quando l'attuatore è completamente inserito.

Fondamentalmente il numero e il tipo di sensori si riduce a eseguire un'analisi dei costi dei sensori rispetto a un'analisi dei requisiti di ciò che è necessario per ottenere la funzionalità richiesta.

    
risposta data 13.06.2017 - 19:31
fonte
-1

C'è un altro pattern che non è stato ancora menzionato riguardo alla gestione del secondo caso che ha un blocco vuoto. Un modo per affrontarlo sarebbe tornare nel blocco if. In questo modo:

void foo()
{
    if (condition) return;

    doStuff();
    ...
}

Questo è un modello comune per il controllo delle condizioni di errore. Il caso affermativo è ancora usato, e l'interno non è più vuoto, lasciando ai futuri programmatori di chiedersi se un no-op fosse intenzionale o meno. Può anche migliorare la leggibilità in quanto potrebbe essere necessario creare una nuova funzione (interrompendo così grandi funzioni in funzioni individuali più piccole).

    
risposta data 08.06.2017 - 22:06
fonte
-1

Le regole di stile concrete sono sempre cattive. Le linee guida sono buone, ma alla fine ci sono spesso casi in cui puoi rendere le cose più chiare facendo qualcosa che non segue le linee guida.

Detto questo, c'è molto odio per il resto vuoto "spreca righe" "digitando in eccesso", che sono solo cattive. Puoi rendere l'argomento per spostare le parentesi sulla stessa linea se hai veramente bisogno dello spazio verticale, ma se questo è un problema non dovresti mettere il tuo {su una linea separata comunque.

Come accennato altrove, avere il blocco else è molto utile per mostrare che desideri esplicitamente che nulla avvenga nell'altro caso. Dopo aver fatto un sacco di programmazione funzionale (dove altro è richiesto), ho imparato che dovresti sempre considerare il resto quando scrivi il if, anche se come @OldCurmudgeon menziona ci sono davvero due diversi casi d'uso. Uno dovrebbe avere un altro, uno non dovrebbe. Purtroppo non è qualcosa che si può sempre dire a prima vista, figuriamoci con un linter, quindi il dogmatico "mette sempre un altro blocco".

Per quanto riguarda i "no negativi", ancora una volta, le regole assolute sono cattive. Avere un vuoto se può essere strano, specialmente se è il tipo di se non ha bisogno di altro, quindi scrivendo tutto questo piuttosto che un! o un == falso è cattivo. Detto questo, ci sono molti casi in cui il negativo ha un senso. Un esempio comune sarebbe il caching di un valore:

static var cached = null

func getCached() {
    if !cached {
        cached = (some calculation, etc)
    }

    return cached
}

se la logica effettiva (mentale / inglese) coinvolge un negativo, così dovrebbe essere la dichiarazione if.

    
risposta data 13.06.2017 - 15:23
fonte

Leggi altre domande sui tag