it-swarm.it

Le parentesi graffe dovrebbero apparire sulla propria linea?

Le parentesi graffe dovrebbero essere sulla loro linea o no? Cosa ne pensi?

if (you.hasAnswer()) {
    you.postAnswer();
} else {
    you.doSomething();
}

o dovrebbe essere

if (you.hasAnswer())
{
    you.postAnswer();
}
else
{
    you.doSomething();
}

o anche

if (you.hasAnswer())
    you.postAnswer();
else
    you.doSomething();

Per favore sii costruttivo! Spiega perché, condividi esperienze, esegui il backup con fatti e riferimenti.

284
Tamara Wijsman

Quando ero uno studente mettevo le parentesi graffe sulla stessa riga, in modo che ci fossero meno righe e il codice venisse stampato su meno pagine. Guardare un singolo carattere tra parentesi stampato come l'unica cosa in una riga è fastidioso. (ambiente, spreco di carta)

Ma quando si codificano applicazioni di grandi dimensioni, consentire alcune linee con solo parentesi graffe sono convenienti, considerando la sensazione di "raggruppamento" che dà.

Qualunque stile tu scelga, sii coerente in modo che non diventi un sovraccarico per il tuo cervello elaborare più stili in parti di codice correlate. In diversi scenari (come sopra) direi che va bene usare stili diversi, è più facile 'cambiare contesto' ad alto livello.

90
dbza

Non dovresti mai fare il terzo metodo.

Scremare le parentesi graffe potrebbe farti risparmiare qualche battitura di tasti la prima volta, ma il programmatore successivo che arriva, aggiunge qualcosa alla clausola else senza notare che il blocco manca di parentesi graffe che causeranno molto dolore.

Scrivi il tuo codice per altre persone.

251
rhettg

Per molto tempo ho sostenuto che avevano lo stesso valore, o giù di lì molto vicino all'uguale che il possibile guadagno facendo la scelta giusta era molto, molto, al di sotto del costo della discussione a riguardo.

Essere coerente è importante, però. Quindi ho detto di lanciare una moneta e di iniziare a scrivere il codice.

Ho visto programmatori resistere al cambiamento in questo modo prima. Farsene una ragione! Ho cambiato molte volte nella mia carriera. Uso persino stili diversi nel mio C # rispetto a PowerShell.

Qualche anno fa stavo lavorando su un team (~ 20 sviluppatori) che ha deciso di chiedere input, quindi prendere una decisione e quindi applicarlo su tutta la base di codice. Avremmo 1 settimana per decidere.

Molti gemiti e strabilianti. Un sacco di "Mi piace la mia strada, perché è meglio" ma nessuna sostanza.

Mentre stavamo studiando i punti più fini della domanda, qualcuno ha chiesto come affrontare questo problema in stile controvento:

void MyFunction(
    int parameterOne,
    int parameterTwo) {
    int localOne,
    int localTwo
}

Si noti che non è immediatamente ovvio dove finisce l'elenco dei parametri e inizia il corpo. Confrontare con:

void MyFunction(
    int parameterOne,
    int parameterTwo) 
{
    int localOne,
    int localTwo
}

Abbiamo fatto alcune letture su come le persone in tutto il mondo hanno affrontato questo problema e abbiamo trovato lo schema di aggiungere una riga vuota dopo la parentesi graffa aperta:

void MyFunction(
    int parameterOne,
    int parameterTwo) {

    int localOne,
    int localTwo
}

Se hai intenzione di fare una pausa visiva, puoi anche farlo con un tutore. Quindi anche le interruzioni visive diventano coerenti.

Modifica: due alternative alla soluzione 'linea in bianco extra' quando si usa K&R:

1/Rientra gli argomenti della funzione in modo diverso dal corpo della funzione

2/Posiziona il primo argomento sulla stessa riga del nome della funzione e allinea altri argomenti su nuove righe a quel primo argomento

Esempi:

1 /

void MyFunction(
        int parameterOne,
        int parameterTwo) {
    int localOne,
    int localTwo
}

2 /

void MyFunction(int parameterOne,
                int parameterTwo) {
    int localOne,
    int localTwo
}

/ Edit

Continuo a sostenere che la coerenza è più importante di altre considerazioni, ma se non abbiamo un precedente stabilito, allora la parentesi graffa sulla linea successiva è la strada da percorrere.

206
Jay Bazuzi

Le regole cardinali sono:

  1. Seguire lo standard di codifica esistente del progetto.
  2. Se non esiste uno standard di codifica e stai modificando una base di codice esistente di proprietà di qualcun altro, sii coerente con lo stile del codice esistente, non importa quanto ti piaccia/non ti piaccia.
  3. Se stai lavorando a un progetto sul campo verde, discuti con altri membri del team e raggiungi un consenso su uno standard di codifica formale o informale.
  4. Se stai lavorando a un progetto sul campo verde come unico sviluppatore, prendi una decisione e poi sii spietatamente coerente.

Anche se non hai vincoli esterni su di te, è meglio (IMO) cercare uno standard di codifica (ampiamente usato) esistente o linee guida di stile, e provare a seguirlo. Se sposti il ​​tuo stile, ci sono buone probabilità che verrai a pentirti tra qualche anno.

Infine, uno stile che è implementato/implementabile usando checker di stili e formattatori di codice esistenti è migliore di uno che deve essere "applicato" manualmente.

103
Stephen C

Il vantaggio del primo metodo è che è più compatto verticalmente, quindi puoi adattare più codice sullo schermo ed è per questo che lo preferisco. L'unico argomento che ho sentito a favore del secondo metodo è che rende più semplice accoppiare parentesi di apertura e chiusura, ma la maggior parte degli IDE ha una scorciatoia da tastiera per questo, ed è in realtà una dichiarazione falsa, invece di associare una parentesi di apertura a una chiusura parentesi puoi associare una parentesi quadra di chiusura all'espressione "inizio del blocco" (if, else, for, while) sullo stesso livello di rientro, quindi è altrettanto facile determinare dove si trova l'inizio del blocco.

Non vedo alcun motivo per sprecare un'intera linea solo per una parentesi quando il precedente per/while/if costrutto indica visivamente l'inizio di un blocco.

Detto questo, credo che la parentesi di chiusura dovrebbe essere nella sua stessa linea perché abbiamo bisogno di qualcosa che indichi la fine di un blocco e la sua struttura di rientro in modo visibile.

72
EpsilonVector

Preferisco

if (you.hasAnswer())
{
    you.postAnswer();
}
else
{
    you.doSomething();
}

al di sopra di

if (you.hasAnswer()) {
    you.postAnswer();
} else {
    you.doSomething();
}

perché la riga you.postAnswer(); è molto più facile da leggere e trovare a prima vista. Nel secondo modo, si fonde con la linea sopra di esso (you.hasAnswer()) facendo sì che i miei occhi debbano concentrarsi maggiormente per leggerlo.

49
JD Isaacks

Preferisco il primo metodo. Le parentesi graffe non valgono assolutamente una linea separata.

Il fatto è che le parentesi graffe non sono importanti. Sono solo cestino sintattico, che è assolutamente inutile per capire a cosa serve il codice, al suo scopo e al modo in cui è implementato. Sono solo un omaggio ai linguaggi di tipo C vecchio stile in cui il raggruppamento visivo degli operatori era impossibile a causa dello spazio disponibile sullo schermo ridotto.

Ci sono lingue (Python, Haskell, Ruby) che vanno bene senza parentesi graffe. Ciò conferma solo che le parentesi graffe sono spazzatura e non dovrebbero meritare una linea per loro quando possibile:

if (you.hasAnswer()){
    you.postAnswer();
}else{
    you.doSomething();
}
39
P Shved

Usa Python e elimina completamente l'argomento.

37
Mark Ransom

La posizione delle parentesi graffe dovrebbe essere

meta data

configurabile in IDE dal programmatore. In questo modo, quelle fastidiose parentesi graffe in tutto il codice, indipendentemente dall'autore, sembrano uguali.

28
Jonathan

Preferisco il primo perché è più difficile per me vedere l'errore in questo esempio.

if (value > maximum);
{
    dosomething();
}

di quanto non sia in questo esempio

if (value > maximum); {
    dosomething();
}

Il ; { mi sembra più sbagliato di una riga che termina con ; quindi ho maggiori probabilità di notarlo.

19
bmb

Dipende.

Se sto codificando in Javascript o jQuery, utilizzo il primo modulo:

jQuery(function($) { 
    if ($ instanceOf jQuery) { 
        alert("$ is the jQuery object!"); 
    } 
}); 

Ma se sto codificando in C #, uso il secondo modulo, perché quello è il modo canonico per farlo in C #.

public int CalculateAge(DateTime birthDate, DateTime now) 
{ 
    int age = now.Year - birthDate.Year; 
    if (now.Month < birthDate.Month 
        || (now.Month == birthDate.Month && now.Day < birthDate.Day)) 
        age--; 
    return age; 
} 

Nota che il tuo esempio può essere scritto

if (you.hasAnswer())
    you.postAnswer();
else
    you.doSomething();

in C #.

19
Robert Harvey

Preferisco una leggera variante di 1)

if (you.hasAnswer()) {
    you.postAnswer();
} // note the break here
else {
    you.doSomething();
}

Perché?

  • Penso che sempre mettere parentesi graffe sulla propria riga riduce la leggibilità. Posso solo inserire una certa quantità di codice sorgente sul mio schermo. Bracket style 2) crea algoritmi pesanti con molti loop nidificati e condizionali dolorosamente lunghi.

  • Tuttavia, voglio che else inizi su una nuova riga perché if e else appartengono insieme, visivamente. Se c'è una parentesi davanti a else, è molto più difficile individuare ciò che appartiene a cosa.

  • 3) si squalifica. Sappiamo tutti quali cose brutte possono accadere se si lasciano le parentesi e se ne dimentica.

15

Ho letto da qualche parte che gli autori di alcuni libri volevano che il loro codice fosse formattato in questo modo:

if (you.hasAnswer())
{
    you.postAnswer();
}
else
{
    you.doSomething();
}

Ma i vincoli di spazio del loro editore significavano che dovevano usare questo:

if (you.hasAnswer()) {
    you.postAnswer();
} else {
    you.doSomething();
}

Ora non so se sia vero (dato che non riesco più a trovarlo), ma quest'ultimo stile è molto diffuso nei libri.

A livello personale preferisco le parentesi su una riga separata come:

a) indicano un nuovo campo di applicazione
b) è più facile individuare quando hai una mancata corrispondenza (anche se questo è meno un problema in un IDE che evidenzia errori per te).

10
ChrisF

Ah, il One True Brace Style .

Ha tutto ciò che serve per una via santa - persino un profeta (Richard "la mia strada o l'autostrada" Stallman).

Il ragazzo aveva talmente torto su così tante cose, ma GNU è perfetto per le parentesi graffe.


[Aggiornamento] Ho visto la luce e ora adoro Allman

Risposta semplice: cosa è più facile eseguire il debug?

// Case 1:
void dummyFunction() {
  for (i = 0; i != 10; ++i) {
    if (i <= 10)
      std::cout << "i is: " << i << "\n";
      std::cout << 10 - i << " steps remaining\n";

      // Some hard work here
      // which is really hard
      // and does take some screen estate
    }
    else
      std::cout << "We'll never get there";
  }
} // COMPILER ERROR HERE


// Case 2:
void dummyFunction()
{
  for (i = 0; i != 10; ++i)

    if (i <= 10)
    {
      std::cout << "i is: " << i << "\n";
      std::cout << 10 - i << " steps remaining\n";

      // Some hard work here
      // which is really hard
      // and does take some screen estate
    }
    else
      std::cout << "We'll never get there\n";
  }
} // COMPILER ERROR HERE

In quale caso hai diagnosticato prima il problema?

Non mi interessa molto per le preferenze personali (ci sono molti altri stili, tra cui bianco e al.) E non mi interessa molto ... fintanto che non ostacola la mia capacità di leggere il codice e debug esso.

Per quanto riguarda l'argomento "spreco di spazio", non lo compro: tendo comunque ad aggiungere righe vuote tra gruppi logici per rendere più chiaro il programma ...

9
Matthieu M.

Secondo esempio, sono molto interessato alla leggibilità. Non sopporto di guardare se i blocchi in qualche altro modo = (

9
Bryan Harrington

Non che nessuno lo noterà, ma questo è il motivo per cui le parentesi graffe appartengono al stessa riga del condizionale (tranne per i condizionali molto lunghi, ma questo è un caso Edge):

In C, questo è un costrutto valido:

 while (true); 
 {
 char c; 
 getchar (); // Attendi input 
} 

Presto! Cosa fa questo codice? Se hai risposto "loop infinito chiedendo input", ti sbagli! Non arriva nemmeno all'input. Viene catturato da while(true). Si noti quel punto e virgola alla fine. Questo modello è in realtà più comune di come dovrebbe essere; C richiede di dichiarare le variabili all'inizio di un blocco, motivo per cui ne è stata avviata una nuova.

Una riga di codice è un pensiero. Le parentesi graffe sono una parte del pensiero contenente il condizionale o il ciclo. Pertanto, appartengono al stessa riga.

8
Christian Mann

Mi piace il primo metodo. Sembra più pulito IMO ed è più compatto, che mi piace.

EDIT: Ah, un terzo. Mi piace il migliore quando possibile, poiché è ancora più piccolo/ordinato.

5
Ullallulloo

Puoi scriverlo:

you.hasAnswer() ? you.postAnswer() : you.doSomething();

Per rispondere alla domanda; Preferivo le parentesi graffe sulla loro stessa linea, ma, per evitare di dover pensare ai bug dell'inserimento automatico del punto e virgola nei browser, ho iniziato a utilizzare lo stile egiziano per javascript. E quando ho programmato Java in Eclipse non avevo interesse a combattere (o configurare) lo stile di controvento predefinito, quindi sono andato anche con l'egiziano in quel caso. Ora sto bene con entrambi.

5
FeatureCreep

Quasi tutte le risposte qui dicono alcune variazioni su "Qualunque cosa tu faccia, resta con una o due".

Quindi ci ho pensato per un momento e ho dovuto ammettere che non lo vedo così importante. Qualcuno può dirmi onestamente che è difficile seguire quanto segue?

int foo(int a, Bar b) {
    int c = 0;
    while(a != c)
    {
        if(b.value[a] == c) {
            c = CONST_A;
        }
        c++;
    }
    return c;
}

Non sono sicuro di nessun altro ... ma ho assolutamente zero problemi a passare mentalmente avanti e indietro tra gli stili. Mi ci sono voluti alcuni istanti per capire cosa facesse il codice, ma questo è il risultato del fatto che ho semplicemente scritto in modo casuale una sintassi simile a C. :)

Secondo la mia opinione non così modesta, l'apertura delle parentesi graffe è quasi del tutto irrilevante per la leggibilità del codice. Ci sono alcuni casi angolari sopra elencati in cui uno stile o l'altro fa la differenza, ma per la maggior parte, l'uso giudizioso delle righe vuote lo pulisce.

FWIW, i nostri stili di codifica al lavoro usano una forma leggermente più strutturata 1 e una forma modificata 3. (C++)

            // blank line is required here
if (x) {
            //This blank line is required
   y = z;
}
            // blank line is required here too, unless this line is only another '}'

if (x) y = z; //allowed

if (x)
    y = z;  // forbidden

Sono curioso di sapere se coloro che preferiscono fortemente la forma 2 troverebbero meglio questa versione della forma 1, solo perché la linea vuota dà una separazione visiva più forte.

4
jkerian

Sono sorpreso che questo non sia stato ancora sollevato. Preferisco il secondo approccio perché ti consente di selezionare il blocco più facilmente.

Quando le parentesi graffe iniziano e terminano sulla stessa colonna e sulla loro stessa riga, è possibile selezionare dal margine o con il cursore sulla colonna 0. In genere ciò equivale a un'area più generosa con la selezione del mouse o un numero inferiore di tasti con la selezione della tastiera.

Inizialmente ho lavorato con le parentesi graffe sulla stessa linea del condizionale, ma quando sono passato ho scoperto che ha accelerato la velocità con cui ho lavorato. Naturalmente non è giorno e notte, ma è qualcosa che ti rallenterà leggermente lavorando con le parentesi graffe accanto ai tuoi condizionali.

4
Tim O'Neil

La mia preferenza personale è per il primo metodo, probabilmente perché è così che ho imparato PHP per la prima volta.

Per istruzioni if a riga singola, userò

if (you.hasAnswer()) you.postAnswer();

Se non è you.postAnswer(); ma qualcosa di molto più lungo, come you.postAnswer(this.AnswerId, this.AnswerText, this.AnswerType); probabilmente tornerò al primo tipo:

if (you.hasAnswer) {
    you.postAnswer(this.AnswerId, this.AnswerText, this.AnswerType);
}

Non userò mai un'interruzione di riga e non userò mai questo metodo se c'è anche un'istruzione else.

if (you.hasAnswer()) you.postAnswer();
else you.doSomething()

è una possibilità teorica, ma non quella che avrei mai usato. Questo dovrebbe essere trasformato in

if (you.hasAnswer()) {
    you.postAnswer();
} else {
    you.doSomething();
}
2
TRiG

Personalmente mi piace il secondo modo.

Tuttavia, il modo in cui ho intenzione di dimostrare è secondo me migliore perché si traduce in una maggiore sicurezza del lavoro! Un compagno di studi della mia università mi ha chiesto aiuto per i suoi compiti e questo è l'aspetto del suo codice. L'intero programma sembrava un singolo blocco. La cosa interessante è che il 95% dei bug nel programma che ha fatto proviene da parentesi graffe non corrispondenti. L'altro 5% era evidente una volta abbinati gli apparecchi.

while(1){
i=0;
printf("Enter coded text:\n");
while((s=getchar())!='\n'){
         if(i%1==0){
            start=(char*)realloc(input,(i+1)*sizeof(char));
if(start==NULL){
printf("Memory allocation failed!");
exit(1);}
input=start;}
      input[i++]=s;}
start=(char*)realloc(input,(i+1)*sizeof(char));
if(start==NULL){
printf("Memory allocation failed!!!");
exit(1);}
input=start;
input[i]='\0';
                puts(input);
2
AndrejaKo

Non dovrebbero; primo metodo per me.

Quando guardo il secondo, a causa delle linee inutilizzate (quelle che contengono solo parentesi graffe, oltre all'ultima parentesi graffa di chiusura), sembra che interrompa la continuità del codice. Non riesco a leggerlo così velocemente perché devo prestare particolare attenzione alle righe vuote che di solito significano una separazione nello scopo del codice o qualcosa del genere, ma in nessun caso "questa riga appartiene a una parentesi graffa" (che ripete solo il significato di rientro).

Ad ogni modo, proprio come quando scrivi un testo ... l'aggiunta di un rientro all'inizio di un paragrafo è superflua se c'è una riga vuota prima di essa (doppio segno di modifica del paragrafo), non è necessario sprecare le righe per le parentesi graffe quando siamo rientro corretto.

Inoltre, come già detto, consente di inserire più codice nello schermo, che altrimenti è un po 'controproducente.

2
Joanis

Dipende dalla piattaforma/lingua/convenzioni

In Java:

void someMethod() { 
     if (you.hasAnswer()) {
         you.postAnswer();
     } else {
       you.doSomething();
     }
}

In C #

void someMethod() 
{ 
     if (you.hasAnswer()) 
     {
         you.postAnswer();
     } 
     else 
     {
       you.doSomething();
     }
}

In C:

void someMethod() 
{ 
     if (you_hasAnswer()) {
         you.postAnswer();
     } else {
       you_doSomething();
     }
}

Odio quando Java usano il loro stile nel codice C # e viceversa.

2
OscarRyz

Uso il primo metodo semplicemente perché è più compatto e consente più codice sullo schermo. Io stesso non ho mai avuto problemi con l'associazione delle parentesi graffe (le scrivo sempre insieme all'istruzione if prima di aggiungere la condizione e la maggior parte degli ambienti consente di passare alla parentesi graffa corrispondente).

Se hai hai bisogno di accoppiare visivamente le parentesi graffe, preferirei il secondo metodo. Tuttavia, ciò consente meno codice alla volta, il che richiede di scorrere di più. E questo, almeno per me, ha un impatto maggiore sulla lettura del codice piuttosto che avere parentesi graffe ben allineate. Odio lo scorrimento. Inoltre, se è necessario scorrere una singola istruzione if, è molto probabilmente troppo grande e necessita di refactoring.

Ma; la cosa più importante di tutte è la coerenza. Usa l'uno o l'altro, mai entrambi!

1
gablin

Tutto quello che posso dire è che se sei un fan del metodo n. 3, sarai perseguitato da ogni IDE codice-formattatore sulla terra.

1
Phil Cohen

C'è una quarta opzione che mantiene le parentesi graffe allineate, ma non spreca spazio:

if (you.hasAnswer())
{    you.postAnswer();
     i.readAnswer();
}
else
{   you.doSomething();
}

L'unico problema è che la maggior parte delle autoformatters di IDE soffocano su questo.

0
AShelly

Quando ho appreso per la prima volta la programmazione a 12 anni, ho messo le parentesi graffe sulla riga successiva perché i tutorial di programmazione Microsoft sono così. Quella volta ho anche frugato con TABS a 4 spazi.

Dopo alcuni anni, ho imparato Java e JavaScript, e ho visto più parentesi graffe sulla stessa riga, quindi ho cambiato. Ho anche iniziato a rientrare con gli spazi di 2 spazi.

0
Ming-Tang