În programare , o convenție de denumire este un set de reguli pentru denumirea identificatorilor care reprezintă variabile , tipuri , funcții și alte lucruri în codul sursă și documentație .
Convențiile, în loc să utilizeze nume arbitrare, pot fi folosite pentru a îndeplini următoarele sarcini:
Alegerea convențiilor de numire poate fi o problemă extrem de controversată, susținătorii fiecăruia văzând convențiile lor ca fiind cele mai bune, iar altele ca cele mai rele. În limbajul obișnuit, astfel de discuții sunt numite „holivars” (din engleză holy war - holy war ) [2] . Multe companii își stabilesc propriile acorduri [3] [4] [5] [6] [7] [8] .
Unele dintre beneficiile potențiale care pot fi obținute prin adoptarea unei convenții de denumire sunt:
Alegerea convențiilor de numire (și măsura în care acestea sunt aplicate) este adesea o problemă controversată, susținătorii rămânând la punctul lor de vedere ca fiind cei mai buni, iar alții ca cei mai rele. Mai mult, chiar dacă există convenții de denumire bine cunoscute și bine definite, unele organizații pot să nu adere la acestea în mod consecvent, ceea ce duce la inconsecvențe și confuzii. Aceste probleme pot fi exacerbate dacă regulile convenției de numire sunt inconsecvente la nivel intern, arbitrare, greu de reținut sau percepute în alt mod ca fiind mai împovărătoare decât utile.
Identificatorii bine aleși fac mult mai ușor pentru dezvoltatori și analiști să înțeleagă ce face sistemul și cum să repare sau să extindă codul sursă pentru a-l aplica noilor nevoi.
De exemplu, desi
a = b * c;corect sintactic , scopul său nu este evident. Compară asta cu:
plată_săptămânală = ore_lucrate * rata_de_pay_orară;ceea ce presupune înțelegerea codului sursă, cel puțin pentru cei familiarizați cu contextul afirmației.
Regulile exacte pentru convențiile de denumire depind de contextul în care sunt utilizate. Cu toate acestea, există câteva elemente comune care influențează majoritatea, dacă nu toate, convențiile de denumire de uz curent astăzi.
Elementele de bază ale tuturor convențiilor de denumire sunt regulile referitoare la lungimea unui identificator (adică numărul finit de caractere distincte permise într-un identificator). Unele reguli prescriu o limită numerică fixă, în timp ce altele specifică valori sau recomandări mai puțin precise.
Regulile privind lungimea identificatorului sunt de obicei contestate în practică și fac obiectul multor dezbateri academice.
Câteva considerații:
Este o întrebare deschisă de cercetare dacă unii programatori preferă identificatori mai scurti, deoarece sunt mai ușor de tastat sau de găsit decât identificatorii mai lungi, sau pentru că în multe situații un identificator mai lung pur și simplu aglomera codul vizibil și nu oferă niciun beneficiu adăugat vizibil.
Concizia programării este parțial explicată prin:
Unele convenții de denumire restricționează afișarea literelor cu litere mari sau mici. Alte convenții nu restricționează literele cu majuscule, dar adaugă o interpretare bine definită, bazată pe literele maritime. Unele convenții de denumire specifică dacă pot fi utilizate caractere alfabetice, numerice sau alfanumerice și, dacă da, în ce ordine.
Recomandarea generală este „Folosiți identificatori semnificativi”. Un cuvânt poate să nu fie la fel de semnificativ sau specific ca mai multe cuvinte. Prin urmare, unele convenții de denumire specifică reguli pentru manipularea identificatorilor „compoziți” care conțin mai mult de un cuvânt.
Deoarece majoritatea limbajelor de programare nu permit spații în identificatori, este necesară o metodă pentru a separa fiecare cuvânt (pentru a facilita cititorii ulterioare să interpreteze caracterele care aparțin unui cuvânt). Din punct de vedere istoric, unele limbi timpurii, în special FORTRAN (1955) și ALGOL (1958), au permis spații în identificatori prin determinarea sfârșitului identificatorilor în funcție de context. Acest lucru a fost abandonat în limbile ulterioare din cauza dificultății tokenizării . Este posibil să scrieți nume prin simpla concatenare a cuvintelor, iar acest lucru este uneori folosit, ca în mypackagenumele pachetelor Java [9] , deși lizibilitatea are de suferit cu termeni mai lungi, deci se folosește de obicei o formă de separare.
Cuvinte separate prin delimitatorO abordare este separarea cuvintelor individuale cu caractere non-alfanumerice. Două caractere sunt utilizate în mod obișnuit în acest scop: o cratimă ("-") și o liniuță de subliniere ("_"); de exemplu, un nume format din două cuvinte «two words»ar fi reprezentat ca «two-words»sau «two_words». Cratima este folosită de aproape toți programatorii COBOL (1959), Forth (1970) și Lisp (1958); este, de asemenea, comun în Unix pentru comenzi și pachete și este folosit în CSS [10] . Această convenție nu are un nume standard, deși poate fi numită lisp-case sau COBOL-CASE (comparați cazul Pascal ), kebab-case , brochette-case , sau alte variații [11] [12] [13] [14] . Dintre acestea , kebab de caz , datând cel puțin din 2012 [15] , a devenit de atunci popular [16] [17] .
În schimb, limbile din tradiția FORTRAN/ALGOL, în special cele din familiile C și Pascal , foloseau cratima pentru operatorul de scădere infix și nu doreau să necesite spații în jurul acestuia (cum ar fi limbajele cu formă liberă), împiedicând-o. utilizarea în identificatori. O alternativă este să folosiți un caracter de subliniere; acest lucru este obișnuit în familia C (inclusiv Python), unde apar cuvinte cu litere mici, cum ar fi în limbajul de programare C (1978) și a devenit cunoscut sub numele de snake case . Literele de subliniere majuscule, ca în UPPER_CASE, sunt utilizate în mod obișnuit pentru macrocomenzile preprocesorului C , deci sunt cunoscute ca MACRO_CASE și pentru variabilele de mediu Unix, cum ar fi BASH_VERSION în bash . Acesta este uneori denumit în mod umoristic SCREAMING_SNAKE_CASE.
Cuvinte separate prin litereO altă abordare este de a indica limitele cuvintelor folosind majuscule din mijloc numite „ camelCase ”, „cazul Pascal” și multe alte nume, afișând astfel «two words»ca «twoWords»sau respectiv «TwoWords». Această convenție este folosită în mod obișnuit în Pascal , Java , C# și Visual Basic . Gestionarea inițialelor în identificatori (cum ar fi „ XML ” și „ HTTP ” în XMLHttpRequest) variază. Unii consideră că ar trebui să fie cu litere mici (de ex XmlHttpRequest. ) pentru ușurință de tastare și lizibilitate, în timp ce alții le lasă cu litere mari (de ex XMLHTTPRequest. ) pentru acuratețe.
Exemple de formate de identificare detaliateFormat | Nume |
---|---|
twowords | carcasă plată [18] [19] |
TWOWORDS | carcasă plată superioară [18] |
twoWords | (inferioară) camelCase , dromedaryCase |
TwoWords | (sus) CamelCase , PascalCase, StudlyCase [20] |
two_words | caz de șarpe , caz de groapă |
TWO_WORDS | SCREAMING SNAKE CASE , MACRO_CASE, CONSTANT_CASE |
Two_Words | Carcasă_Șarpe_cămilă [21] |
two-words | kebab-case , dash-case , lisp-case |
TWO-WORDS | TREN-CASA, COBOL-CASA, SCREAMING-KEBAB-CASA |
Two-Words | Train-Case, [18] HTTP-Header-Case [21] |
Unele convenții de denumire sunt reguli sau cerințe care depășesc cerințele unui anumit proiect sau domeniu și reflectă, în schimb, un set mai larg de principii definite de o arhitectură software , limbaj de programare care stau la baza sau altă metodologie între proiecte.
Poate cea mai cunoscută este notația maghiară , care codifică fie scopul („Apps Hungarian”), fie tipul („Systems Hungarian”) unei variabile din numele acesteia [22] . De exemplu, prefixul „sz” pentru variabila szName indică faptul că variabila este un șir terminat cu nul.
Stilul folosit pentru foarte scurt (opt caractere sau mai puțin) ar putea fi: LCCIIL01, unde LC este atașament (scrisori de credit), C pentru COBOL, IIL pentru un anumit subset de procese și 01 este un număr de secvență.
Această convenție este încă în uz activ în mainframe dependente de JCL și se găsește și în stilul MS-DOS 8.3 (maximum opt caractere cu un punct de separare urmat de un tip de fișier cu trei caractere).
„OF Language” al IBM a fost documentat în manualul IMS ( Information Management System ).
Acesta detaliază schema de cuvinte PRIME-MODIFIER-CLASS, care constă din nume precum „CUST-ACT-NO” pentru „numărul contului clientului”.
Cuvintele PRIME au fost destinate să desemneze principalele „entități” de interes pentru sistem.
Cuvintele MODIFICATOR au fost folosite pentru clarificare suplimentară, rafinare și lizibilitate.
În mod ideal, cuvintele CLASĂ ar fi o listă foarte scurtă de tipuri de date specifice aplicației. Cuvintele obișnuite CLASS pot fi: NU (număr), ID (identificator), TXT (text), AMT (cantitate), QTY (cantitate), FL (steagul), CD (cod), W (lucrare), etc. În practică , cuvintele CLASS disponibile vor fi o listă de mai puțin de două duzini de termeni.
Cuvintele CLASĂ, care sunt de obicei plasate în partea dreaptă (sufix), servesc aproape aceluiași scop ca și prefixele de desemnare maghiară .
Scopul cuvintelor CLASĂ, pe lângă consistență, a fost acela de a indica programatorului tipul de date al unui anumit câmp de date. Înainte de a accepta câmpuri BOOLEAN (doar două valori), FL (steagul) va indica un câmp cu doar două valori posibile.
Convențiile și cele mai bune practici Adobe de codare furnizează standarde de denumire pentru ActionScript care urmează în mare parte standardele ECMAScript . Stilul identificatorilor este similar cu cel al Java .
În Ada , singurul stil recomandat pentru identificatori este Mixed_Case_With_Underscores[23] .
Dialectele APL folosesc o delta (Δ) între cuvinte, cum ar fi PERFΔSQUARE (în mod tradițional nu existau litere mici în versiunile mai vechi ale APL). Dacă în nume sunt folosite litere subliniate, va fi folosită o liniuță delta (⍙) subliniată.
În C și C++ , cuvintele cheie și identificatorii standard ale bibliotecii sunt scrise în mare parte cu litere mici. În biblioteca standard C, abrevierile sunt cele mai comune (de exemplu, isalnumpentru o funcție care verifică dacă un caracter este alfanumeric), în timp ce biblioteca standard C++ utilizează adesea liniuțe de subliniere ca separatori de cuvinte (de exemplu, out_of_range). Identificatorii care reprezintă macrocomenzi sunt prin convenție scriși folosind doar litere mari și liniuțe de subliniere (acest lucru se datorează convenției din multe limbaje de programare de a folosi numai identificatori majuscule pentru constante). Numele care conțin caractere de subliniere duble sau care încep cu un caracter de subliniere și o literă majusculă sunt rezervate implementării ( compilator , bibliotecă standard ) și nu trebuie folosite (de exemplu, __reservedsau _Reserved) [24] [25] . Acest lucru este superficial similar cu slinging-ul, dar semantica este diferită: liniuțele de subliniere fac parte din valoarea identificatorului, mai degrabă decât ghilimele (cum ar fi slinging): valoarea __fooeste __foo(care este rezervată) nu foo(dar într-un spațiu de nume diferit).
Convențiile de denumire C# urmează, în general, recomandările publicate de Microsoft pentru toate limbile NET [26] (vezi NET mai jos), dar compilatorul C# nu impune nicio convenție.
Manualul Microsoft recomandă utilizarea exclusivă doar a PascalCase și CamelCase , acesta din urmă fiind folosit doar pentru numele parametrilor și numele variabilelor de metodă constale valorilor locale (inclusiv metoda locală). O excepție specială pentru PascalCase este făcută pentru acronimele din două litere care încep un identificator; în aceste cazuri, ambele litere sunt IOStreamlitere (de exemplu, IOStream); acest lucru nu se aplică acronimelor mai lungi (de ex XmlStream. ). De asemenea, manualul recomandă ca numele dat interfacesă fie PascalCase precedat de un I majuscul , ca în IEnumerable.
Ghidurile Microsoft privind denumirea câmpurilor se aplică și câmpurilor static; câmpurile care nu sunt și au alte niveluri de accesibilitate (de exemplu și ) nu sunt în mod clar supuse ghidurilor [27] . Cea mai obișnuită practică este să folosiți PascalCase pentru toate numele câmpurilor, cu excepția celor care sunt (și nu sunt nici , nici ), cărora li se dau nume care folosesc camelCase precedate de un singur caracter de subliniere; de exemplu, . publicprotectedstaticinternalprivateprivateconststatic_totalCount
Orice nume de identificare poate începe cu un caracter de ghilimele ( @ ) fără a modifica semnificația. Adică și factor, și @factorse referă la același obiect. Prin convenție, acest prefix este utilizat numai atunci când identificatorul ar fi altfel fie un cuvânt cheie rezervat (de exemplu, forși while) care nu poate fi utilizat ca identificator fără prefix, fie un cuvânt cheie contextual (de exemplu, fromși where), caz în care, prefixul nu este strict necesar (cel puțin nu atunci când îl declarați; de exemplu, deși declarația dynamic dynamic;este validă, de obicei se vede dynamic @dynamic;că indică imediat cititorului că acesta din urmă este un nume de variabilă).
În Go , se obișnuiește să se folosească MixedCapssau mixedCapsmai degrabă decât sublinierea pentru a scrie nume detaliate. Când se face referire la clase sau funcții, prima literă indică vizibilitatea pachetelor externe. Dacă faceți prima literă majusculă, acest fragment de cod va fi exportat, în timp ce literele mici vor fi folosite doar în domeniul curent [28] .
În Java , convențiile de denumire pentru identificatori au fost dezvoltate și propuse de diverse comunități Java, cum ar fi Sun Microsystems [29] , Netscape [30] , AmbySoft [31] , etc. Exemple de convenții de denumire stabilite de Sun Microsystems sunt enumerate mai jos, unde numele în „ CamelCase ” constă din mai multe cuvinte concatenate fără spații, cu litera majusculă inițială a fiecărui cuvânt, cum ar fi „CamelCase”.
Tipul de identificare | Reguli de denumire | Exemple |
---|---|---|
Clase | Numele claselor trebuie să fie substantive în , prima literă a fiecărui cuvânt trebuie să fie scrisă cu majuscule. Folosiți cuvinte întregi - evitați acronimele și abrevierile (cu excepția cazului în care abrevierea este folosită mult mai larg decât forma lungă, cum ar fi URL sau HTML). Upper CamelCase |
|
Metode | Metodele trebuie să fie verbe cu majuscule sau majuscule sau nume cu mai multe cuvinte care încep cu un verb cu minuscule; adică prima literă cu litere mici și primele litere ale cuvintelor următoare cu litere mari. lower CamelCaselower CamelCase |
|
Variabile | Variabilele locale, variabilele de instanță și variabilele de clasă sunt, de asemenea, scrise în . Numele de variabile nu trebuie să înceapă cu un caracter de subliniere ( ) sau semnul dolar ( ), chiar dacă ambele sunt permise. Acest lucru este în contrast cu alte convenții de codare, care afirmă că toate variabilele de instanță ar trebui să fie prefixate cu caractere de subliniere.
lower CamelCase_$ Numele variabilelor ar trebui să fie scurte, dar semnificative. Alegerea numelui variabilei ar trebui să fie mnemonică, adică menită să indice observatorului ocazional scopul utilizării acesteia. Numele variabilelor cu un singur caracter ar trebui evitate, cu excepția variabilelor temporare „unice”. Nume comune de variabile temporare: i, j, k, m și n pentru numere întregi; c, d și e pentru caractere. |
|
constante | Constanțele trebuie scrise cu majuscule, separate prin liniuțe de subliniere. Numele constantelor pot conține și numere dacă este necesar, dar nu ca prim caracter. |
|
Compilatoarele Java nu aplică aceste reguli, dar nerespectarea acestora poate duce la confuzie și cod eronat. De exemplu, widget.expand()și Widget.expand()implică un comportament semnificativ diferit: widget.expand()implică un apel de metodă pe o expand()instanță numită widget, în timp ce Widget.expand()implică un apel de metodă static. expand()in clasa Widget.
Un stil de codare Java utilizat pe scară largă necesită ca UpperCamelCase să fie utilizat pentru clase și lowerCamelCase pentru instanțe și metode [29] . Recunoscând această utilizare, unele IDE -uri precum Eclipse implementează comenzi rapide bazate pe CamelCase. De exemplu, în funcția de asistență pentru conținut Eclipse, introducerea cu majuscule a cuvântului CamelCase va sugera orice nume de clasă sau metodă potrivită (de exemplu, tastarea „NPE” și activarea asistentului de conținut poate sugera NullPointerException).
Inițialisme de trei sau mai multe litere - CamelCase în loc de majuscule (de exemplu, parseDbmXmlFromIPAddressîn loc de parseDBMXMLFromIPAddress). De asemenea, puteți seta un chenar de două sau mai multe litere (de exemplu, parseDbmXmlFromIpAddress).
Bibliotecile JavaScript încorporate folosesc aceleași convenții de denumire ca și Java. Tipurile de date și funcțiile de constructor folosesc litere mari ( RegExp , TypeError , XMLHttpRequest , DOMObject ) iar metodele folosesc litere mici ( getElementById , getElementsByTagNameNS , createCDATASection ). Pentru a fi consecvenți, majoritatea dezvoltatorilor JavaScript urmează aceste convenții [32] [33] .
Practica obișnuită în majoritatea dialectelor Lisp este utilizarea cratimelor pentru a separa cuvintele în identificatori, ca în with-open-fileși make-hash-table. Numele variabilelor dinamice încep și se termină de obicei cu asteriscuri: *map-walls*. Numele constantelor sunt marcate cu semnul plus: +map-size+[34] [35] .
Microsoft .NET recomandă UpperCamelCase , cunoscut și sub numele de PascalCase , pentru majoritatea identificatorilor. Pentru parametri și variabile , se recomandă utilizarea lowerCamelCase ), care este o convenție generală pentru limbajele .NET [36] . De asemenea, Microsoft recomandă să nu folosiți indicații de prefix de tip (cunoscut și ca notație maghiară [37] . În loc să utilizați notația maghiară, este recomandat să terminați numele cu numele clasei de bază: LoginButtonîn loc BtnLoginde [38] .
Objective-C are un stil de programare general înrădăcinat în Smalltalk .
Entitățile de nivel superior, inclusiv clasele, protocoalele, categoriile, precum și constructele C care sunt utilizate în programele Objective-C, cum ar fi variabilele și funcțiile globale, sunt în UpperCamelCase cu un prefix scurt majuscule care denotă spațiul de nume, de exemplu NSString , UIAppDelegate . NSApp sau CGRectMake . Opțional, constantele pot fi prefixate cu „k” minuscule, cum ar fi kCFBooleanTrue .
Variabilele obiect utilizează lowerCamelCase prefixat cu un caracter de subliniere, cum ar fi _delegate și _tableView .
Numele metodelor folosesc mai multe părți LowCamelCase, separate prin două puncte, care separă argumentele, de exemplu: application: didFinishLaunchingWithOptions: , stringWithFormat: și isRunning .
Limbile Pascal, Modula-2 și Oberon folosesc de obicei identificatori Capitalizedsau UpperCamelCasepentru programe, module, constante, tipuri și proceduri și lowerCamelCaseidentificatori lowercasesau lowerCamelCasepentru constante matematice, variabile, parametri formali și funcții [39] . În timp ce unele dialecte acceptă liniuțe de subliniere și semne de dolar în identificatori, snake case și macro case sunt probabil limitate pentru a fi utilizate în API-uri externe [40] .
Perl preia unele reguli din moștenirea sa C. Numele de subprograme variabile și locale sunt scrise cu litere mici, cu caractere de subliniere infixe. Subrutinele și variabilele care ar trebui tratate ca private sunt prefixate cu un caracter de subliniere. Variabilele pachetului sunt incluse într-un antet. Toate constantele declarate sunt scrise cu majuscule. Numele pachetelor sunt scrise cu litere mari, cu excepția pragmelor precum strictși mro, care sunt mroscrise cu litere mici [41] [42] .
Recomandările PHP sunt cuprinse în PSR-1 (recomandarea standard PHP 1) și PSR-12 [43] . Conform PSR-1, numele claselor trebuie să fie în PascalCase, constantele clasei trebuie să fie în MACRO_CASE, iar numele metodelor trebuie să fie în camelCase [44] .
Python și Ruby sunt recomandate UpperCamelCasepentru numele claselor, CAPITALIZED_WITH_UNDERSCORESpentru constante și lowercase_separated_by_underscorespentru alte nume.
În Python, dacă un nume trebuie să fie „ privat ” într-un modul, se recomandă ca acesta să înceapă cu un singur caracter de subliniere. Numele se pot încheia și cu un singur caracter de subliniere pentru a preveni conflictul cu cuvintele cheie Python. Prefixul dublu de subliniere, pe de altă parte, distorsionează reprezentarea externă a numelor membrilor clasei: de exemplu, într-o clasă, FooBaro metodă __boodin afara clasei va fi vizibilă ca _FooBar__boo. Numele care încep și se termină cu o liniuță de subliniere dublă sunt rezervate „numelor magice” care joacă un rol special în Python (de exemplu, __init__, __import__, __file__) [45] .
Deși nu există un ghid de stil oficial pentru R , ghidul de stil tidyverse de la guru-ul R Hadley Wickham stabilește standardul pentru majoritatea utilizatorilor [46] . Acest ghid recomandă evitarea caracterelor speciale în numele fișierelor și utilizarea numai a numerelor, literelor și liniuțelor de subliniere pentru numele de variabile și funcții, cum ar fi fit_models. R.
Raku urmează mai mult sau mai puțin aceleași reguli ca și Perl, cu excepția faptului că Raku permite cratime interne și apostrofe (ghilimele simple), atâta timp cât sunt întotdeauna urmate de litere. Astfel, kebab -case poate fi folosit în Raku : de exemplu, fish-foodși don't-do-thatsunt identificatori validi [47] .
Rust recomandă UpperCamelCasestruct, trăsătură, enum și enum pentru aliasuri de tip și nume de variante, SCREAMING_SNAKE_CASEpentru constante sau variabile statice și snake_casepentru nume de variabile, funcții și structuri [48] .
Swift își schimbă convențiile de denumire cu fiecare lansare. Cu toate acestea, actualizarea majoră a Swift 3.0 a stabilizat convențiile de denumire pentru lowerCamelCasevariabile și declarații de funcție. Constantele sunt de obicei definite prin tipuri enumerate sau parametri constanți, care sunt, de asemenea, scrisi în același mod. Declarațiile de clase și alte tipuri de obiecte sunt UpperCamelCase.
Începând cu Swift 3.0, au fost formulate linii directoare clare de denumire pentru limbaj cu scopul de a standardiza convențiile de denumire și declarațiile API pentru toate API-urile terțe [49] .