Utilizzo di caratteri singoli per nomi di variabili in cicli / eccezioni [duplicato]

65

Ho avuto un paio di discussioni con un collega sull'uso dei nomi di variabili a lettera singola in determinate circostanze all'interno della nostra base di codici, in cui entrambi non siamo d'accordo.

Preferisce una convenzione di denominazione più dettagliata per questi, e io no.

Sono a mio parere tre scenari in cui utilizzo nomi di variabili a lettera singola:

  • Cicli - i for(int i = 0; i < 10; i++) { ... }
  • Espressioni Lambda in C # - x/y/z : .Where(x => x == 5)
  • Eccezioni - e : try { ... } catch(ExceptionType e) { /* usage of 'e' */ }

Questi sono gli solo scenari in cui vorrei utilizzarlo, e ovviamente uso altre convenzioni di denominazione più dettagliate altrove.

Il mio collega ha avanzato i seguenti argomenti per le eccezioni e i loop:

  • i - non significa niente.
  • e - è la lettera più comune nella lingua inglese. Se si desidera cercare la soluzione per le eccezioni, si troveranno molte istanze indesiderate di e .

Accetto questi argomenti, ma ho replicato che, se uno non sa cosa i significa in un ciclo for, allora probabilmente non dovrebbero essere un programmatore. È un termine molto comune per loop ed eccezioni, come e . Ho anche detto che, se lo si voleva, potevano cercare catch nel caso dell'eccezione.

Mi rendo conto che questo è soggettivo, ma poi, si potrebbe sostenere che gli standard di codifica sono proprio questo: le opinioni, anche se le opinioni degli accademici.

Sarei felice in ogni caso, e gli inoltrerò i risultati, ma preferirei che noi (la nostra azienda) continuassimo a utilizzare un singolo standard di codifica, piuttosto che avere due sviluppatori con opinioni diverse su cosa usare.

    
posta Dan Atkinson 27.04.2011 - 19:15
fonte

20 risposte

79

Sono completamente d'accordo con la tua opinione, e credo che non sia tutto quello soggettivo.

Il nome di una variabile è rilevante solo come ambito.

Non c'è motivo di discutere senza fine su un nome di una variabile che verrà letto solo da una persona che legge quel particolare pezzo di codice ristretto. D'altra parte, i nomi delle classi e dei nomi dei membri devono indicare chiaramente cosa sta succedendo. Molti dei comportamenti attesi devono essere spiegati con un nome sintetico.

Le convenzioni migliorano la leggibilità.

i e e sono convenzioni comuni utilizzate per quelle piccole variabili con scope. Il loro intento è molto chiaro se conosci la convenzione.

La concisione migliora la leggibilità.

Un nome di variabile breve che rappresenta chiaramente il suo intento è da preferire a un nome di variabile grande.

    
risposta data 27.04.2011 - 12:52
fonte
54

Questo dipende molto dalla situazione / contesto (e non esiste una soluzione one fits all ).

In generale i, j, k [btw, i può essere preso come index ; il suo utilizzo deriva da un background matematico in cui erano più spesso i primi tre indici (ricorda il calcolo del tensore). Può anche essere collegato alla cronologia di Fortran, dove i è il primo intero implicitamente tipizzato, spesso utilizzato come indice di un ciclo. ] sono spesso usati se si tratta di un semplice contatore. Se ha un significato specifico, come month o year , il nome della variabile più lungo è migliore.

    
risposta data 27.04.2011 - 18:19
fonte
21

Sono d'accordo con te: i come nome di una variabile di ciclo è un idioma antico che non dovrebbe confondere nessuno. Come e per una variabile di eccezione in un blocco catch. Quest'ultimo (o piuttosto entrambi) dovrebbe essere breve e semplice, rendendo la portata della variabile piccola, limitando la possibilità di confusione per i lettori. E se qualcuno vuole cercare delle eccezioni, cerca meglio i tipi di eccezioni o cattura i blocchi comunque.

Detto questo, personalmente preferisco usare nomi di variabili a ciclo più lungo come index o idx . La mia ragione è che i è così breve, è difficile da localizzare con il cursore.

Aggiornamento

Per riferimento, gli argomenti del tuo collega probabilmente provengono da Regole di Ottinger per i nomi - un approccio eccellente e pragmatico al soggetto, raccomandato per la lettura. Tuttavia, potrebbe aver trascurato le parti citate qui sotto:

My personal preference is that single-letter names can ONLY be used as local variables inside short methods. The length of a name should somehow correspond to the size of its scope. If a variable or constant might be seen or used in multiple places in a body of code it is imperative to give it a search-friendly name.

E

Certainly a loop counter may be named i or j or k (though never l!) if its scope is very, very small and no other names can conflict with it. These are allowable because those are traditional solution-domain names.

    
risposta data 18.05.2011 - 09:36
fonte
15

nomi più prolissi possono essere altrettanto privi di significato. "i" è così comunemente usato come semplice contatore di iterazioni, è pratica quasi standard. Chiamare lo stesso contatore "iter" perché alcuni "standard di codifica" proibiscono nomi di variabili a lettera singola non aggiungono alcun valore.

"x", "y" e "z" sono nomi di coordinate standard, chiamandoli xCoord, yCoord, zCoord non aggiunge nulla.

"e" ovviamente è un'espressione matematica. Ma è relativamente comune usarlo come nome per le eccezioni nei blocchi catch in Java. Chiamarlo "exc" o qualcosa di simile non aggiungerebbe di nuovo valore reale.

    
risposta data 27.04.2011 - 12:28
fonte
15

Preferisco nomi di variabili significativi, anche per variabili di loop. Quindi, di solito scrivo qualcosa come

for (int vertexIndex=0; vertexIndex<polygon.VertexCount; vertexIndex++)
   DoSomethingWithVertex(polygon[vertexIndex]);

Mi rendo conto che c'è poca differenza (in entrambi i casi) per un piccolo ciclo come questo, ma:

  • se il corpo del ciclo è più lungo, vertexIndex è spesso più chiaro di i . Ovviamente i è un indice, ma quale indice? A quale array? A quale elemento di quell'array?
  • se il corpo del loop chiama altre funzioni e passa l'indice come argomento, è spesso più semplice assegnare un nome al valore in modo coerente al chiamante e alle posizioni del punto di chiamata e non si desidera chiamare i parametri del metodo i e x
  • se ci sono cicli annidati, usando i , j , k come indici è molto confuso e soggetto a errori

per essere coerenti, uso solo nomi di variabili significativi per gli indici di loop ovunque.

@ André Paramés ha chiesto: "Se il corpo del loop è abbastanza lungo da nascondere il significato di i, non è il momento di refactoring?"

Un tipico cervello umano ha una capacità di memoria a breve termine di circa 7 blocchi di dati. Quindi se il corpo del ciclo contiene 8 o più blocchi (dove "blocchi" sono dichiarazioni, variabili locali, parametri, commenti), il tuo cervello non può memorizzare simultaneamente il significato di ciascuno di questi blocchi. Invece, il tuo cervello sposterà i pezzi dentro e fuori dalla memoria di lavoro mentre leggi il codice. Ad esempio, se usi nomi di variabili come i e j , il tuo cervello sposterà i significati di i e j dalla sua memoria di lavoro; la prossima volta che leggerai j , il tuo cervello di solito si baserà sul contesto per trovare il significato, ad esempio se leggi customers[j] nel mezzo del corpo del ciclo, il tuo cervello inferirà quel j è un indice nell'array customers . Se avessi scritto customers[vertexIndex] , vedresti che stai usando l'indice sbagliato. E questo è per corpi di loop molto brevi con solo 8 blocchi di informazioni, cioè 5-8 linee di codice.

Se il corpo si allunga, normalmente lo estrai in una funzione separata con un parametro vertexIndex . E questo è il secondo punto che stavo facendo: se la variabile è chiamata vertexIndex all'interno di quella funzione, dovrebbe essere chiamata anche vertexIndex anche al chiamante.

    
risposta data 28.04.2011 - 15:24
fonte
10

Non sono d'accordo con i tuoi colleghi punti.

Per me, intendo "iterazione". Abbastanza significativo nel caso di un ciclo.

La maggior parte degli IDE consentono ricerche di tipo regex attraverso il testo. Quindi puoi cercare 'e' non all'interno di una parola. Sarebbe efficace.

    
risposta data 27.04.2011 - 12:19
fonte
6

(Questo è .NET-centric ma la tua domanda ha menzionato le espressioni lambda C #, quindi penso che questo sia rilevante nel tuo caso.)

Userei sempre ex per un'eccezione, poiché e è già utilizzato (dalle convenzioni WinForms e WebForms di ASP.NET) come argomento EventArgs -typed per un gestore di eventi.

per es.

protected void button_Click(object sender, System.EventArgs e)
{
    try
    {
        // whatever
    }
    catch (Exception ex)
    {
        // some exception handling
    }
}

Tuttavia, MSDN utilizza e per variabili di eccezione .

Durante questa discussione suggerisco di tenere a mente due cose:

  • Le convenzioni di denominazione variabile di solito possono essere considerate una forma di guerra religiosa .
  • La più importante convenzione di codifica è mantenere lo stile del codice esistente .
risposta data 27.04.2011 - 14:37
fonte
5

Non vedo alcuna domanda qui, ma "i", "j" di solito si riferiscono alle coordinate proprio come "x" e "y" (la mia preferenza personale), capisco che "e" potrebbe essere troppo comune, ma se cerchi le eccezioni, fai clic su "Eccezione".

il problema più grande nell'usare variabili a lettera singola è che potresti confondervi con loro, ma se questa variabile ha un ambito limitato, come in un ciclo o in un tentativo di cattura, non vedo alcun problema con esso

    
risposta data 27.04.2011 - 12:22
fonte
5

Di solito non è molto rilevante quando si ha un loop singolo, e preferisco usare i o j per semplicità (e per convenzione). Con il ciclo annidato, a volte uso nomi più dettagliati per riconoscere quale indice si riferisce a cosa. Per esempio, se ho due array: di date e di quantità, e ho un ciclo annidato che itera prima su date, e poi su quantità, userei nomi dateIdx e quantityIdx, per evitare confusione. Ho avuto bug nel mio codice quando ho scritto

matrix[i][j] = fun(dates[i], quantities[j]);

ma dovrebbe avere

matrix[i][j] = fun(dates[j], quantities[i]);

Con più nomi dettagliati, avrei facilmente individuato l'errore, come

matrix[quantityIdx][dateIdx] = fun(dates[quantityIdx], quantities[dateIdx]);

sembrerebbe sbagliato.

    
risposta data 27.04.2011 - 12:45
fonte
5

I nomi brevi delle variabili sono come pronomi nei linguaggi naturali: da usare in un contesto / ambito ristretto. "i" in un ciclo breve (senza nidificazione) o "e" in una sequenza di poche catture sono perfettamente a posto. In molti casi il nome lungo / descrittivo di "i" sarebbe "the_stupid_index_needed_to_get_at_the_really_interesting_things" e si utilizza un'espressione lambda solo perché è necessaria in un solo contesto.

Perl's $ _ è un super-pronome che funziona (per programmatori Perl); anche se essere autorizzato / incoraggiato a saltare anche 'it' (solo "print" a "print $ _") è qualcosa di cui ho un po 'paura.

La ricerca di nomi di variabili per individuare problemi nel codice non sarebbe la mia prima idea. Penso che il programmatore dovrebbe avere un'idea della classe o della funzione in cui cercare in caso di problemi specifici.

    
risposta data 27.04.2011 - 12:45
fonte
4

Una domanda epistemologica interessante è quella di che significa . Il tuo collega sembra presumere che solo perché qualcosa significa qualcosa per lui , allora c'è è che significa e in caso contrario non lo è.

La verità è, naturalmente, che tutti quei simboli che usiamo ogni giorno, non solo nella programmazione, hanno un significato solo perché li attribuiamo a loro. Oppure, per dirla in modo diverso, il significato è nel tuo cervello, non nel simbolo. (Per dirlo chiaramente a quelli di noi, pensate a una tavoletta cuneiforme - sicuramente aveva un significato per gli scrittori una volta, eppure per la maggior parte dei miliardi di persone che oggi non ha.)

Alla luce di ciò, l'ipotesi che nomi lunghi significhi qualcosa, mentre i nomi brevi no, è assurda. Inoltre, l'aspettativa che un nome lungo in un testo di un programma porti in qualche modo il significato che potrebbe avere in un contesto diverso può portare a confusione.

    
risposta data 27.04.2011 - 12:52
fonte
4

Alcuni punti:

  • Ho sentito suggerire che dovresti preferire usare "ii" a "i" perché se mai dovessi cercare il tuo indice di loop sarai in grado di farlo (ed è visivamente più distinto in generale ), e penso che sia una buona idea.
  • Dipende dall'ambito e dal contenuto del tuo loop. Se il tuo loop fa semplicemente qualcosa 10 volte (per esempio se non accede affatto nemmeno alla variabile loop), allora penso che "i" o "ii" sia mille volte più ragionevole di un nome più lungo. Chiunque abbia mai programmato dovrebbe sapere o imparare che "i" normalmente significa "variabile di loop"
  • Se il tuo loop ha un blocco di codice molto grande all'interno, considera di estrapolarlo a una funzione, ma in entrambi i casi potrebbe essere utile avere un breve ma un nome significativo, ad es. carIdx o day, non ultimo perché potresti voler usare "i" all'interno del corpo del loop.
  • Se il loop scorre ripetutamente sul contenuto di una struttura dati, utilizzare un nome pertinente: un'abbreviazione o una forma minuscola del tipo di dati o della variabile contenuta se è ragionevolmente distintivo (ad esempio auto di ricerca in autoOwned) o una forma più lunga se il tuo ciclo è più complesso.
  • Penso che lo stesso valga per lambda ed eccezioni, anche se sono meno familiare. Per esempio, se c'è un nome ragionevole per l'input del tuo lambda, specialmente se ce n'è più di uno, allora usalo, ma la maggior parte delle volte, l'intero POINT di un lambda è di prendere un input anonimo, che tutti comprendono " x "per significare molto bene.
risposta data 27.04.2011 - 13:18
fonte
4

Quando parli di codice leggibile, devi prendere in considerazione alcuni aspetti:

  • Quali sono i tuoi standard di codifica?
  • Quali sono le convenzioni più comuni per la tua piattaforma?
  • C'è il potenziale per la confusione?

Supponendo che gli standard di codifica non parlino molto delle convenzioni di denominazione delle variabili, dovresti pensare a discutere del codice. Ad esempio con il loop sottostante:

for(int i = 0; i < 10; i++)
{
    function(i);
}

Il loop e tutte le sue funzioni possono essere chiaramente visti per l'intera gamma. Ora, immagina se abbiamo cicli annidati (il mio preferito è il ciclo all'interno di un ciclo all'interno di un ciclo); o forse un ciclo che si estende su 100 linee. A quel punto, gli iteratori a lettera singola non hanno molto senso, perché è così facile perdersi nella portata. Potresti voler refactoring che 100 linee di codice in alcuni metodi / funzioni per domare un po ', ma dare l'indice un nome significativo.

Riguardo alle eccezioni, tenderei a convenire che e non sia un buon nome. Tuttavia, le mie ragioni sono diverse da quelle del tuo amico. Ho fatto un sacco di programmazione Java nel corso degli anni e ho dovuto gestire tutte quelle brutte eccezioni controllate che non verranno mai lanciate a meno che qualcuno non esegua l'installazione di Java. È un dato di fatto. Quindi, man mano che gestisci un'eccezione, devi incapsulare parte della tua gestione delle eccezioni all'interno di un altro gestore di eccezioni. Un posto comune che si verifica è con il codice JDBC.

In conclusione, dal momento che ogni eccezione che stavi verificando ha bisogno di un nome univoco e stai gestendo diversi tipi di errori in una clausola di prova, dai quei nomi di eccezioni che significano qualcosa. Vedere e , e1 , e2 non aiuta quando sto leggendo il codice. Che tipo di eccezione sto guardando? Quindi, di nuovo, dato che c'è spazio per la confusione, usa nomi lunghi.

    
risposta data 27.04.2011 - 14:23
fonte
3

Uso i come contatore nei cicli solo quando:

  • è usato come indice; e
  • quando il suo ambito è molto breve.

Come diceva Rook, il termine i ha uno sfondo matematico come indice che viene etichettato come convenzione di programmazione. Tuttavia, se si tratta di un loop lungo, contenente molte variabili, rinominerei il contatore i in qualcosa di più esplicito. Se hai cicli annidati che eseguono l'iterazione su una matrice, di solito uso row e col invece come i e j non sono esattamente chiari rispetto a cosa si riferiscono più ("Era A[i][j] o A[j][i] ...? ").

Riguardo e per le eccezioni tendo a usare ex perché ho visto e essere usato per element .

    
risposta data 27.04.2011 - 14:55
fonte
2

Si riduce alla differenza tra "Cosa stai facendo?" contro "Come stai?"

Innanzitutto, se possibile, utilizza un foreach anziché un for . Esprime meglio ciò che stai facendo (ad esempio, cammina attraverso la raccolta ed elabora ciascun elemento). Questo elimina il problema di denominare del tutto.

Se la variabile index ha un significato diverso da "the_stupid_index_needed_to_get_at_the_really_interesting_things" (grazie E.H.), usa quel significato. row e col devono essere preferiti su i e j se l'array rappresenta una tabella. Mi piace anche usare position o pos se sto facendo un sacco di scambio.

Tuttavia, l'idioma for (int i = 0 ....) è così ben stabilito, che è lo standard di fatto per un'iterazione. Non scherzare con un linguaggio ben consolidato senza una buona ragione.

Eccezione sopra: matematica o fisica: utilizza le formule standard del testo.

v = d/t; è più familiare a un fisico o ingegnere di velocity = distance / time;

    
risposta data 27.04.2011 - 15:17
fonte
1

Sebbene non abbia problemi ad usare "i", gli standard di condanna richiedono qualcosa di più. Non perderei tempo a discutere se è necessario. Per me "loopIndex" e "loopCounter" sono due nomi standard che uso al posto di "i".

    
risposta data 27.04.2011 - 12:50
fonte
1

@ nikie elenca già alcuni dei miei argomenti, ma voglio aggiungere che il tuo argomento per limitare la verbosità è debole.

Esaminando il codice da solo, sarebbe più utile un nome più descrittivo. Identificare il loop stesso non è un problema come quello che hai menzionato.

Utilizzerai la "i" più volte in un'app e potresti salvare alcuni tipi di digitazione, ma non tutti si riferiscono alla stessa cosa. Molti script SQL generano alias una tabella con una singola lettera, ma ogni volta che viene utilizzata, si riferisce alla stessa tabella.

Presentarsi con nomi significativi può essere difficile, motivo per cui è meglio farlo diventare un'abitudine.

    
risposta data 27.04.2011 - 13:38
fonte
1

Ho pensato che i significasse "incremento". Penso che il gran numero di risposte diverse indichi che c'è qualcosa nella domanda originale sulla significatività dei nomi delle variabili - spesso significano qualcosa di tradizionale, ma molte persone li usano senza sapere quale sia la tradizione. È facile dire che qualcuno che non sa cosa significhi i per "non dovrebbe essere un programmatore", ma come si impara cosa significa i ? Ci sono una mezza dozzina di risposte proprio qui.

    
risposta data 27.04.2011 - 17:14
fonte
1

Steve McConnell in Code Complete aveva un ottimo consiglio per la prolissità dei nomi delle variabili, tutto dipende dall'ambito e dall'uso della variabile. Se hai una classe grande, le tue variabili membro hanno nomi chiari come vuoi sapere cosa rappresenta la variabile quando sei sepolto nel codice a metà del file. Se hai una funzione breve o una variabile usata solo per poche righe di codice puoi fare il meno possibile, dato che non ti confonderai su dove è definito o cosa rappresenta, e un nome più piccolo rende il codice più chiara.

Quindi per il tuo caso, i, ee x sono grandi nomi di variabili. (presumendo ovviamente che non si abbiano grandi loop complessi)

    
risposta data 28.04.2011 - 00:02
fonte
1

Per "e" , che ovviamente significa "eccezione" o "errore", è facile cercare eccezioni, devi solo assicurarti che la tua ricerca corrisponda a parole intere (potrebbe anche cercare "e)" con abbinando parole intere, se non usi uno spazio tra la variabile e le parentesi), non troverai molte "e" tutte da sole, tranne nei gestori di eccezioni.

Per "i" , ha un significato: sta per "iteratore" (o forse "indice" o "incrementor").

C'è un altro motivo per avere un nome di variabile breve: scorciatoie a nomi di variabili / classi più lunghi che vengono usati molto spesso in un framework o cosa hai. Come il JQuery "$" .

    
risposta data 28.04.2011 - 02:25
fonte

Leggi altre domande sui tag