Domanda

Sto programmando in linguaggi derivati ??da C ormai da un paio di decenni. Da qualche parte lungo la linea, ho deciso che non volevo più scrivere:

if (var)    // in C
if ($var)   # in Perl

quando intendevo dire:

if (var != 0)
if (defined $var and $var ne '')

Penso che parte di ciò sia che ho un cervello fortemente tipizzato e nella mia mente, "se" richiede un'espressione booleana.

O forse è perché uso così tanto Perl e la verità e la menzogna in Perl sono un tale campo minato.

O forse è solo perché oggigiorno sono principalmente un programmatore Java.

Quali sono le tue preferenze e perché?

È stato utile?

Soluzione

Mi piace il mio if per avere un senso quando letto ad alta voce:

if (is_it_happening) ...
if (number_of_sheep != 0) ...
if (pointer_to_something != NULL) ...

Altri suggerimenti

Preferisco

if (var != 0)

È più facile da leggere / capire. Dal momento che scrivi il codice una volta ma leggi parecchie volte, la lettura facile è più importante della scrittura facile.

È abbastanza semplice. if (var) verifica la veridicità. if (var! = 0) verifica che non sia il numero 0. NON SONO INTERCAMBIABILI! Ci sono tre ragioni.

Innanzitutto, usare if (var! = 0) per verificare la verità è più complicato. C'è semplicemente altro da leggere e capire. Devi capire che ! = e 0 è il linguaggio di " è vero " ;. In mancanza di un modello visivo distintivo, devi fare un po 'più di studio per sapere che non è lo stesso di if (var == 0) . Questa è una sottile distinzione, ma vale la pena menzionarla. Il fatto che esista lo stile if (0! = Var) dà credito. Meglio semplicemente eliminare il problema e usare if (var) per la verità.

Secondo, e soprattutto, l'intento deve essere chiaro. Stai testando la verità o stai testando un numero (o la sua mancanza)? if (var) sta testando la verità, if (var! = 0) sta testando un numero. Per determinare qualsiasi altra cosa è necessario avere una conoscenza dello stile dell'autore, cosa che dobbiamo presumere che non sia il programmatore della manutenzione.

In terzo luogo, c'è un'ipotesi sul valore degli operatori veri, falsi e numerici che potrebbero funzionare in alcune lingue e non in altre. In Perl, e penso anche a Javascript, la stringa vuota è falsa. Molti operatori restituiscono stringhe vuote per false. Quindi testare la verità con if (var! = 0) porta ad un avvertimento. Diventa più severo quando fai qualcosa di più ingenuo come if (var == 1) per dire la verità, un presupposto chiaramente pericoloso. Mi sembra che molti programmatori junior lo scrivano e, a loro volta, scrivano funzioni che restituiscono numeri dispari, ma veri, per punire questo genere di cose. O quando sono di buon umore, ho disinfettato il mio valore di ritorno con return var? 1: 0 .

In una nota correlata, Perl restituirà l'ultima espressione valutata da una subroutine, quindi non è necessario scrivere return . Combina questo con l'idea che le persone hanno che il return esplicito è più lento e molte persone abusano di questo fatto.

sub set {
    my( $self, $key, $value ) = @_;

    $self->{$key} = $value;
}

set restituirà $ value . Era previsto? Non lo so. Quello che so è che qualcuno inizierà a fare affidamento su di esso. E il programmatore di manutenzione non saprà se può cambiarlo. Quindi mi piace inserire esplicitamente un ritorno in ogni subroutine non banale.

sub set {
    my( $self, $key, $value ) = @_;

    $self->{$key} = $value;
    return;
}

In quel caso ho deciso che set non restituirà nulla per il momento e questa decisione sarà abbastanza chiara sia per il lettore che per l'utente.

if (var)

Meno da scrivere, purché tu sia sicuro di non provare la cosa sbagliata.

Preferisco test espliciti a meno che il risultato tra parentesi non sia un valore booleano esplicito. La frase "if (1)", sebbene sintatticamente e semanticamente corretta in termini di lingua, non è logica. Dovrebbe essere vero o falso, non trasmesso automaticamente.

Preferisco il codice logico leggibile per scrivere meno ogni giorno.

Disprezzo anche il codice veemente del modulo:

if (gotError == FALSE) ...
if (isComplete == TRUE) ...

Se il valore booleano è chiamato correttamente (e dovrebbe essere), il modo giusto per farlo è:

if (!gotError) ...
if (isComplete) ...

Questo perché (usando reductio ad absurdum) boolVal == TRUE è semplicemente un altro valore booleano, quindi dove ti fermi?

if (isComplete == TRUE) ...
if ((isComplete == TRUE) == TRUE) ...
if (((isComplete == TRUE) == TRUE) == TRUE) ...
if ((((isComplete == TRUE) == TRUE) == TRUE) == TRUE)...

E così via, all'infinito.

Direi che se stai confrontando un numero intero vero, allora non fare mai una conversione implicita in booleano, poiché implica un significato diverso per la variabile.

Ma ancora una volta quello stile è così popolare che probabilmente non è un grosso problema, ma dal mio lavoro con C #, scrivo il mio codice C ++ in questo stile:

Booleano o int che è fondamentalmente un booleano:

if (val)

Numero intero vero con più che vero / falso importante:

if (val != 0)

Puntatore di qualche tipo:

if (val != NULL)

Ma come molti diranno sugli stili di codifica che non fanno alcuna differenza funzionale, è probabilmente meglio essere coerenti e, se si lavora con codice esistente, essere coerenti con quel codice.

In Perl if (definito $ var e $ var ne '') e if ($ var) NON sono equivalenti. Provalo con $ var = 0 . Al contrario, se esegui il test su $ var! = 0 tutte le stringhe che non possono essere convertite in numeri non supereranno il test (con un avviso se le hai attivate).

Quindi devi sapere esattamente cosa contiene la tua variabile (numero o stringa, se può essere undef ) in modo da poter testare di conseguenza.

Di solito scrivo if ($ var) e lascio che Perl se ne occupi. Credo che sia più facile da leggere e che sia lo stile più comune in Perl.

Molto spesso, in realtà, il test corretto finisce per essere if (definito $ var) . Ecco dove è utile il nuovo operatore (in 5.10) // di perl. $ var = $ val // $ default o spesso $ var // = $ default , dove $ var riceverà $ default solo se $ val (resp $ var ) è undef .

In Javascript (non conosco altre lingue dinamiche)

if (x) 

e

if (x != 0)

significa cose diverse. Userò il primo quando mi aspetto che x contenga un riferimento a un oggetto o una stringa che non dovrebbe avere lunghezza zero. È un linguaggio abbastanza noto.

Se hai un valore destinato a essere un valore booleano, dovresti sentirti a tuo agio nel fare:

if ( var )
if ( $var )

Se hai requisiti più specifici per il tuo " booleano, " puoi sempre eseguire alcuni lavori di preparazione / test sulla tua variabile e assegnarla a un'altra variabile con valori booleani meglio definiti.

$shouldDoSomething = ( defined $var and $var ne '' ) ? 1 : 0;

if ( $shouldDoSomething ) {
    // Handle this case.
}

Questo può ripulire un po 'il codice. Aiuta anche se si intende utilizzare questa condizione più di una volta. Trovo che questo accada abbastanza frequentemente, in realtà. Inoltre, credo che quanto sopra sia molto più leggibile che farlo in linea:

if ( defined $var and $var ne '' ) {
    // Handle this case.
}

Vado con leggibilità come la maggior parte delle persone, mi piace essere in grado di scansionare il mio codice e leggerlo senza pensare troppo, va di pari passo con nomi di variabili ben definiti. Se i nomi delle tue variabili fanno sembrare che dovrebbe essere un semplice if (isPurchasable) allora vado con esso comunque si riferisce a un numero o data o fasion simile che uso if (stock > 0) .

Dover scrivere un commento per un'istruzione if anche a me è un'idea orribile se l'espressione è così semplice, un'istruzione if come sotto anche se posso vedere perché i commenti dovrebbero essere usati.

if(isPurchasable && stock > 0 && credit >= cost && !reserved) { 
     // Checks to see if customer can purchase product.
}

Per gli scalari di valori numerici, tendo a scrivere if ($ num_foo) quando $ num_foo è sotto il mio controllo. Se è l'input dell'utente o è passato dall'esterno, prima lo numico o scrivo esplicitamente il test. Dipende da molti fattori. Il criterio principale è quando e come è conveniente gestire valori non definiti, al fine di evitare avvisi.

Per verificare la presenza di stringhe non vuote, scrivevo if ($ foo) perché l'incantesimo corretto è semplicemente una battitura eccessiva:

if ( defined $foo and length $foo )

Ma non ero soddisfatto di questo stato di cose, quindi Ho istigato un cambiamento di comportamento per length undef in Perl 5.12 , che genera un avviso e restituisce 0 fino a Perl 5.10 incluso. In 5.12 sarà silenzioso return undef . Pertanto, in contesti non booleani viene comunque visualizzato un avviso, che si verifica solo dopo aver valutato la chiamata length anziché prima. Ma in contesti booleani, non ci sono avvisi, quindi è molto più semplice controllare correttamente una stringa non vuota:

if ( length $foo )

Ho molti modi per farlo:

per i booleani:

if (x)

per ints:

if (x != 0)  // always compare, never assume true/false on int values

per puntatori:

if (x /* != 0 */)  // I've always done this, not sure where I picked it up but I like it

In questi giorni, penso che sia meglio avere una chiamata di funzione che descriva cosa significa effettivamente la logica all'interno dell'istruzione if

EDIT: Nota, lo 0 (intsead di NULL) è perché uso principalmente C ++ in questi giorni

Sono sorpreso che nessuno abbia menzionato l'altra opzione, sostenuta dagli standard di codifica di un mio precedente datore di lavoro:

if( 0 != x );

Dove la costante è stata sempre elencata per prima (soprattutto più importante con i confronti, dato che occasionalmente si sbagliano agli incarichi - la fonte di molti bug)

È lo stile che ho usato da allora nel mio C / Perl / C ++ / VB.Net poiché (ovviamente il punto diventa moot in C # che in realtà non consente il if (x) scenario (a meno che x non sia effettivamente un valore booleano, ovviamente).

In C # è stato esplicitamente illegale scrivere

if(x){}

a meno che x sia un tipo booleano. Non esiste una conversione implicita in bool della maggior parte degli altri tipi.

Ho usato molto questo modulo scrivendo JavaScript, PHP e simili per verificare che non siano nulli. Ma poi ho ricevuto alcuni bug (facilmente rilevabili) da esso ... Immagino che staremmo meglio senza di essa.

Quando lo uso su variabili booleane, credo fermamente in nomi facilmente leggibili. Di solito, chiamo variabili booleane usate in questo modo con nomi che iniziano con " is " ;, " has " o qualcosa di simile.

In genere preferisco if (var) o if ($ var) se var viene utilizzato come valore booleano, anche se non è presente ' t qualsiasi tipo di questo tipo nella lingua.

Non mi piacciono molto i costrutti come if (! strcmp (...)) o if (var == true) . Il primo cerca di essere troppo intelligente, il secondo troppo stupido, anche se si adatta bene a if ((var == true) == true) , ... ;-)

Alcuni linguaggi, come Perl e C ++, forniscono interpretazioni extra o addirittura definite dall'utente. Se la conversione in un booleano sembra troppo magica, ricorda che in pratica è solo un is_true (var) o var.booleanValue () , o qualcosa del genere dietro la scena, solo un sintassi più concisa.

In relazione alla tua domanda, mi piace formulare le condizioni in modo positivo. Invece di

if (!condition) {
    g();
}
else {
    f();
}

Preferisco

if (condition) {
    f();
}
else {
    g();
}

Anche se esiste un solo ramo e la condizione non è tremendamente semplice. (Un'indicazione per questo è la necessità di un commento.) Ad esempio, invece di

// explain reason for condition here
if (!condition) {
    f();
}

Preferisco esprimerlo come

if (condition) {
    // explain condition here
}
else {
    f();
}

Per il mio modo di pensare, la semplicità è la migliore.

Più semplice è il codice, meglio è. Inoltre, meno è probabile che tu commetta errori. Pertanto, vorrei utilizzare

if(var)

Ma alla fine, dovresti usare ciò che funziona meglio per il tuo modo di pensare.

Non sempre lo gestisco, ma provo a usare

if (0 != var)

quindi corrisponde allo stile difensivo

if (0 == var)

Se hai un int-bool in C che contiene già un flag (e non un conteggio), e lo stai testando con " if (var! = 0) " ;, dove finisce? Non sarebbe " if ((var! = 0)! = 0) " essere ancora meglio? : -)

Preferisco un nudo:

if ($canDo) {
}

invece di qualcosa del tipo:

if ($canDo == true) {
}

Laddove un condizionale sia del tutto complicato, lo commento esplicitamente con un commento o implicitamente con un buon nome di variabile. Cerco anche di essere molto esplicito quando si imposta una variabile booleana, preferendo:

my($canDo) = !0;

a

my($canDo) = 1;

Quest'ultimo è confuso; perché assegnare un valore discreto a un valore booleano?

Dati i molti significati di Perl per "valutare vero", tuttavia, posso vedere perché essere più espliciti è più pratico a lungo termine. Tuttavia, una delle cose che mi piace di più di Perl è la sua naturale fluidità linguistica, e preferisco nel mio codice attenermi a ciò (lasciando i commenti e i nomi delle variabili per chiarire ulteriormente le cose, se necessario).

VBScript? Bene questo bit di codice dichiara una Variante, quindi bFlag è zero, che è effettivamente un Falso.

Dim bFlag
If bFlag Then

Non mi piace. Quindi, anche in VB, con l'opzione di dichiarazioni più specifiche, mi trovo ad essere esplicito, qualunque sia il tipo.

Dim bFlag As Boolean
If bFlag = False Then

L'altro problema riguardava le regole di denominazione variabile. Se stai usando un regime influenzato dall'Ungheria, allora puoi dire visivamente che una determinata variabile è booleana, quindi essere specifici sul fatto che sia vera o falsa è meno un problema. Se, tuttavia, stai usando qualche altra tecnica di denominazione variabile, o peggio, la denominazione in un modo ad hoc, allora è appropriato essere specifici su ciò che viene testato.

Molto spesso uso:

 if(x) {
       DoSomething;
       DoSomething2;
     }

Perché questo è meno scritto e libro che la lettura diceva:

  

Pochi buoni programmatori usano il modulo if (x! = 0) , usano if (x) .

Ma a volte usa e altre forme:

if(x!=0) 

HNY! : -)

Trovo che se (X) {/ * ... * /} è molto più facile da leggere (almeno in C).

Se non mi aspetto che nessun altro legga il codice, saremo noi quello breve. Se mi aspetto che qualcuno legga effettivamente il mio codice, prenderei in considerazione l'utilizzo del modulo lungo per la leggibilità.

Mi piacciono le costruzioni Python:

if var:
    return "I like the way I do it!"

È solo per esempio ;-)

Ci sono lingue in cui non hai scelta. In Specman, ad esempio, non puoi scrivere:

var x: uint;

if (x) {
    bla
};

Ma tu puoi fare:

var x: uint;

if (x != 0) {
    bla
};

o

var x: bool;

if (x) {
    bla
};

Tuttavia, non puoi farlo:

var x: bool;

if (x != 0) {
    bla
};

Perché non puoi confrontare un valore booleano con un numero intero.

Venendo da C e Perl ho sempre pensato che fosse fastidioso, fino a quando non ho iniziato a scrivere molto su Specman. Il codice è semplicemente più chiaro in questo modo.

Secondo me, if (var! = 0) è migliore.

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