È una cattiva pratica usare la valutazione di cortocircuito invece di una clausola if? [duplicare]

6
    

Questa domanda ha già una risposta qui:

    

Sto lavorando su uno script di installazione, e in particolare ho molte cose da controllare e azioni che devono essere eseguite solo in caso di risultati correlati. Ad esempio, una cartella deve essere creata solo se non esiste:

MyDesktopFolderPath := AddBackslash(ExpandConstant('{commondesktop}')) +
                         'My Folder';
if not DirExists(MyDesktopFolderPath) then
begin
  ForceDirectories(MyDesktopFolderPath); //Create full path
end;
if DirExists(MyDesktopFolderPath) then
begin
  //Perform other actions

Invece di questo, potrei usare (sfruttare?) la valutazione del cortocircuito per renderlo più compatto:

MyDesktopFolderPath := AddBackslash(ExpandConstant('{commondesktop}')) +
                        'My Folder';
IsMyDesktopFolderExisting := DirExists(MyDesktopFolderPath) or
                               ForceDirectories(MyDesktopFolderPath);
if IsMyDesktopFolderExisting then
begin
  //Perform other actions

Anche questo funzionerebbe, ma mi chiedo se sia una cattiva pratica, soprattutto perché è meno ovvio che le azioni possano essere eseguite. Qualche opinione su questo?

Modifica: come indicato da Secure, il codice non è completamente equivalente, ma l'argomento della discussione è ancora valido per altri casi.

    
posta thoiz_vd 18.09.2011 - 20:07
fonte

7 risposte

12

"Buone pratiche" - NO. Come i tuoi coetanei potrebbero non essere intelligenti come te. Ma sì, in alcune lingue (oserei dire Perl), questo è un idioma comune. Ma "sfruttare" la valutazione del cortocircuito - se fosse considerata una buona pratica,

  1. È sicuramente sarebbe sembrato essere un idioma comune in un posto come il sorgente del kernel di Linux (Quei ragazzi giurano di scrivere il codice più chiaro sulla terra).
  2. Se ... Allora..Else sarebbe stato eliminato ormai.

Quindi, il mio suggerimento, mantienilo semplice, anche se significa qualche altra sequenza di tasti. Solo un'osservazione e un'opinione personale, però.

    
risposta data 18.09.2011 - 20:57
fonte
9

Il cortocircuito è stato aggiunto come mezzo per migliorare le prestazioni quando si valuta un'espressione booleana. Usarlo come una forma di flusso di controllo può portare a confusione molte persone non si aspettano che valutare un'espressione abbia un effetto collaterale. Nella maggior parte dei casi, essere più espliciti su ciò che si sta facendo è meglio per la leggibilità.

Se guardi questo esempio, lo sfruttamento del cortocircuito ti fa risparmiare solo due righe. A mio avviso, ciò non è sufficiente per accettare i potenziali problemi che potrebbero sorgere dall'effetto collaterale implicito. Per evitare la confusione, è possibile aggiungere un commento per spiegarlo. Ma non stai diminuendo il risparmio del numero di linee. Alla fine, è necessario eseguire una semplice operazione e, sfruttando questa funzione, si riduce la chiarezza dell'operazione. Ora devi aggiungere una spiegazione invece di lasciare che il codice parli da solo.

    
risposta data 18.09.2011 - 20:56
fonte
6

La valutazione del cortocircuito non riguarda solo le prestazioni. Si tratta anche di prevenire errori di runtime. Ad esempio, vorrei prendere in considerazione:

if (foo != null && foo.bar == 4) {
    // do something
}

per essere perfettamente chiaro e preferibile a

if (foo != null) {
    if (foo.bar == 4) {
        // do something
    }
 }

Nota che il primo modulo funziona solo se esiste una valutazione di cortocircuito ... altrimenti genera un errore di runtime ogni volta che foo == null .

    
risposta data 19.09.2011 - 00:15
fonte
6

Per me va bene; questo è un idioma molto comune in molte lingue: sh, C ++, Perl, Lisp, Ruby, ecc.

Non aggiungerei un commento; il commento non aggiungerebbe nulla al codice.

Non ho molta simpatia per i colleghi che non possono essere disturbati ad analizzare un codice leggermente non familiare.

    
risposta data 19.09.2011 - 02:37
fonte
1

Questo è il codice Delphi-Pascal - l'impostazione di un booleano usando "o" potrebbe essere considerata un'offuscazione, ma non credo che uno sviluppatore attento e con esperienza possa avere qualche problema con esso - Uso questo costrutto molto frequentemente e non ho mai ha avuto un reclamo.

Tuttavia, nella maggior parte dei casi limiterei una scorciatoia ad una condizione: se stringete insieme alcune condizioni per ottenere un valore booleano, state sicuramente tassando il lettore e introducendo potenziali bug sgradevoli.

Per inciso, se comprendo correttamente il tuo codice, nel secondo esempio, "se IsMyDesktopFolderExisting allora" non è necessario: a quel punto la condizione è sempre true.

Inoltre: primo esempio: 'se DirExists (MyDesktopFolderPath)' tutto ciò che serve qui è 'else' - boolean è binario: è vero o falso. - Se questo non è ciò che dovrebbe accadere qui, questo codice ha bisogno di refactoring.

    
risposta data 18.09.2011 - 22:19
fonte
0

Se pensi che qualcuno possa essere confuso da un costrutto, ci sono due soluzioni:

  1. Scrivi un commento che spiega cosa hai fatto.
  2. Scriverlo in un modo meno confuso.

Se ritieni che devi fare n. 1 più spesso di quanto desideri, prova il n. 2.

    
risposta data 18.09.2011 - 21:24
fonte
0

La tua prima versione potrebbe essere così:

IsMyDesktopFolderExisting := DirExists(MyDesktopFolderPath);
if not IsMyDesktopFolderExisting then
begin
  IsMyDesktopFolderExisting := ForceDirectories(MyDesktopFolderPath);
end;
if IsMyDesktopFolderExisting then
...

Mentre uso un cortocircuito mi dice di guardare più attentamente cosa è fatto qui, ignorando il valore di ritorno di una funzione di gestione risorse (come memoria o file) si alza immediatamente una bandiera rossa.

    
risposta data 19.09.2011 - 10:55
fonte

Leggi altre domande sui tag