Namespace ( ing. namespace ) - un set , care înseamnă un model, un spațiu de stocare abstract sau un mediu creat pentru gruparea logică a identificatorilor unici (adică nume).
Un identificator definit într-un spațiu de nume este asociat cu acel spațiu de nume . Același identificator poate fi definit independent în mai multe spații. Astfel, o valoare asociată cu un identificator definit într-un spațiu de nume poate avea sau nu aceeași valoare ca același identificator definit într-un alt spațiu de nume. Limbile care știe spațiul de nume definesc reguli care indică spațiului de nume căruia îi aparține un identificator (adică definiția acestuia).
De exemplu, Andrey lucrează în compania X, iar ID -ul său (abreviat din engleză Identificator - identificator) ca angajat este 123. Oleg lucrează în compania Y, iar ID-ul său este, de asemenea, 123. Singurul lucru (din punctul de vedere al vedere a unui anumit sistem de contabilitate), datorită a ceea ce Andrey și Oleg pot fi distinși cu ID-uri potrivite este apartenența lor la diferite companii. Diferența dintre companii în acest caz este un sistem de spații de nume diferite (o companie - un spațiu). Prezența a doi angajați într-o firmă cu același act de identitate prezintă mari probleme la utilizarea acestora, de exemplu, va fi foarte greu de determinat angajatul căruia îi este destinat acest cec dintr-un salariu care va indica un angajat cu ID 123.
În bazele de date mari, pot exista sute sau mii de identificatori. Spațiile de nume (sau structuri similare ) oferă un mecanism pentru ascunderea identificatorilor locali. Sensul lor este de a grupa identificatorii corelați logic în spațiile de nume respective, făcând astfel sistemul modular . Limitarea vizibilității variabilelor se poate face și prin specificarea clasei de stocare a acesteia .
Sistemele de operare , multe limbaje de programare moderne își acceptă propriul model de spațiu de nume: folosesc directoare (sau foldere) ca model de spațiu de nume. Acest lucru permite să existe două fișiere cu același nume (atâta timp cât sunt în directoare diferite). În unele limbaje de programare (de exemplu , C++ , Python ), identificatorii de nume de spațiu sunt ei înșiși asociați cu spațiile corespunzătoare. Prin urmare, în aceste limbi, spațiile de nume se pot cuibări unele în altele, formând un arbore de spații de nume. Rădăcina unui astfel de arbore se numește spațiu de nume global .
În limbajele de programare, una dintre modalitățile de a specifica limita spațiului de nume poate fi utilizarea așa-numitului. domeniul de aplicare .
Spațiul de nume este definit de un bloc de instrucțiuni:
spatiu de nume foo { int bar ; }În cadrul acestui bloc, identificatorii pot fi apelați exact așa cum au fost declarați. Dar în afara blocului, numele spațiului de nume trebuie specificat înaintea identificatorului. De exemplu, în afara namespace fooidentificatorului barar trebui specificat ca foo::bar. C++ conține alte constructe care fac aceste cerințe opționale. Deci, atunci când adăugați o linie
folosind namespace foo ;cod, foo::nu mai trebuie să specificați un prefix. Alt exemplu:
spațiu de nume Spațiu de nume12 { int foo = 0 ; } void func1 () { folosind namespace Namespace12 ; // acum toate numele din spațiul de nume Namespace12 vor fi vizibile aici fără prefixe suplimentare ++ foo ; } void func2 () { // și aici trebuie specificat numele: Namespace12 :: foo = 42 ; }Codul care nu este declarat explicit în spațiul de nume se presupune a fi declarat în spațiul de nume global.
Rezoluția spațiului de nume în C++ este ierarhică. Aceasta înseamnă că într-un spațiu de nume ipotetic еда::суп, identificatorul курицаva reprezenta еда::суп::курица(dacă spațiul există). Dacă nu există, atunci indică еда::курица(dacă acel spațiu există). Dacă nici acest spațiu nu există, atunci se курицаreferă la un identificator din spațiul global.
Spațiile de nume sunt adesea folosite în C++ pentru a evita coliziunile de nume .
spatiu de nume { int a ; void f () { /*...*/ } int g () { /*...*/ } }Nu puteți accesa un membru al unui spațiu de nume anonim dintr-o unitate de traducere dintr-o altă unitate.
Deși spațiile de nume sunt utilizate pe scară largă în codul modern, o mare parte din codul mai vechi nu are aceste caracteristici. De exemplu, întreaga bibliotecă standard C++ este definită în namespace std, dar înainte de standardizare, multe componente au fost definite inițial în spațiul global.
De asemenea, puteți face vizibil nu întregul spațiu, ci nume individuale din el, de exemplu:
spatiu de nume foo { int bar ; int somelse ; } int main () { folosind foo :: bar ; //Face vizibilă numai bara, iar altele invizibilă! returnează 0 ; }Ideea spațiilor de nume este încorporată în pachetele Java . Tot codul este definit într-un pachet, iar pachetul nu are nevoie de un nume explicit. Codul din alte pachete este disponibil prin prefixarea numelui pachetului cu identificatorul corespunzător, de exemplu, o clasă Stringdintr-un pachet java.langpoate fi numită ca java.lang.String(aceasta este cunoscută ca un nume de clasă complet calificat ). Ca și în C++, Java oferă o construcție care face ca specificarea numelui pachetului ( import) să fie opțională. Cu toate acestea, unele caracteristici (cum ar fi reflectarea ) necesită ca programatorul să folosească numele complet calificat.
Spre deosebire de C++, spațiile de nume Java nu sunt ordonate ierarhic din cauza sintaxei limbajului în sine. Cu toate acestea, pachetele sunt denumite într-un stil ierarhic. De exemplu, toate pachetele care încep cu javafac parte din platforma Java - pachetul java.langconține clasele de bază ale limbajului și java.lang.reflectconține clasele de bază specifice reflectării (reflecției).
În Java (precum și în Ada , C# și alte limbi), spațiile de nume/pachetele reflectă categoriile semantice ale codului. De exemplu, în C# namespace Systemconține cod care este implementat de sistem ( platforma .NET ). Cât de exact sunt definite aceste categorii și cât de adâncă este ierarhia depinde de limba în sine.
Domeniul de aplicareO funcție și o clasă pot fi definite ca un spațiu de nume implicit, legat în mod complex de vizibilitatea, accesibilitatea și durata de viață a obiectului .
Există spații de nume în limbajul C#, utilizarea este similară cu C++.
În Python, ideea spațiilor de nume este implementată în module. (La fel ca în pachetele Java)
În ciuda lipsei de suport formal pentru spațiile de nume, acestea sunt ușor de implementat folosind conceptul de obiect al limbajului:
var NameSpace_1 = {}; var NameSpace_2 = obiect nou (); //două spații de nume NameSpace_1 . a = 100 _ NameSpace_2 . a = "Capsuni" ; // Variabile a - fiecare are propriile sale with ( NameSpace_1 ) // Specificați spațiul de nume implicit { a += 10 ; NameSpace_2 . a += a ; //Variabila un spațiu de nume NameSpace_2 va fi egal cu „Strawberry110” }În XML , specificarea spațiilor de nume XML definește unicitatea numelor de elemente și atribute dintr-un document, similar cu rolul spațiilor de nume într-un limbaj de programare. Cu spațiile de nume, documentele XML pot conține nume de elemente sau atribute din mai mult de un dicționar XML.
<rdf:RDF xmlns:rdf= "http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:foaf= "http://xmlns.com/foaf/0.1/" xmlns:rdfs= "http://www.w3.org/2000/01/rdf-schema#" > <foaf:Person rdf:about= "#JW" > …xmlns (XML Namespace) - spațiu de nume XML. Sunt incluse RDF (pentru a crea un document RDF ) , FOAF și Schema RDF ( format de proiectare RDF ).
FOAF este și spațiul unui document RDF , astfel încât designul acestuia este verificat conform vocabularului (reguli, specificații ) RDF .
Începând cu versiunea 5.3.0, PHP a introdus conceptul de spațiu de nume.
<?php namespace my\name ; // definește un nou spațiu de nume clasa MyClass {} function myfunction () {} const MYCONST = 1 ; $a = new MyClass ; // apel în interiorul meu\name space $c = new \my\name\MyClass ; // folosiți numele complet, inclusiv numele spațiului de nume $d = new \globalClass ; // apelarea unei clase din spațiul de nume global ?>Un punct important. Directiva de spațiu de nume trebuie să fie prima linie de cod din fișier. Excepția este cuvântul cheie declare, care poate precede directiva de spațiu de nume. Nici măcar ieșirea HTML înainte de prima construcție „<?php” nu este permisă.
Descrierea sintaxei este pe site-ul oficial al proiectului PHP [1] .
Sintaxa standard Common Lisp are spații de nume de tabel implementate prin sistemul de pachete [2] . Pentru a utiliza un identificator (simbol), trebuie să specificați numele complet al acestuia: numele pachetului, două puncte și numele simbolului însuși [3] .
Allegro Common Lisp implementează o extensie Common Lisp non-standard - spații de nume ierarhice, în care pachetele sunt separate printr-un punct în stilul Java , iar identificatorul de pachete este separat prin două puncte. De asemenea, este posibil să se facă referire la nodurile adiacente din ierarhia spațiului de nume prin specificarea căilor relative prin două puncte [4] . Spațiile de nume din Common Lisp sunt dinamice - sunt create, populate și distruse în timpul execuției programului. , deși se folosește în principal forma declarativă a descrierii lor folosind formularul defpackage[5] .
În PureBasic 5.20 , a fost introdus suportul pentru spațiile de nume, implementat ca module. Spațiul de nume este definit de blocul de comenzi Modul și EndModule și nu depinde de locația din fișierele sursă. Aceasta înseamnă că într-un fișier pot fi mai multe module sau invers - codul modulului poate fi împărțit în mai multe fișiere. Implicit, întreg spațiul modulului este ascuns, iar pentru a face vizibile elementele sale individuale, acestea trebuie declarate într-un bloc special de comenzi DeclareModule / EndDeclareModule. Orice nu este declarat în acest bloc nu este disponibil în afara modulului, iar încercarea de a accesa va avea ca rezultat un mesaj de încălcare a accesului de la compilator.
DeclareModule Count x = 0 ; Elemente publice Declare Counter () EndDeclareModule Număr de module y = 0 _ Elemente private Counter Procedure () y + 1 ProcedureReturn y EndProcedure EndModule Numărare: : x = 10 ; Scrierea unui număr într-o variabilă (de exemplu). Debug Count :: Counter () ; Apelarea unei proceduri folosind numele modulului. UseModule Count ; Maparea unui modul la spațiul curent. Contor de depanare () ; Acces la elemente publice (publice) fără a specifica numele modulului. UnuseModule Count ; Anulați acțiunea UseModule.Pentru a accesa elemente de modul dintr-un alt modul sau spațiu global, trebuie să specificați numele modulului și elementul acestuia, de exemplu: Count::x. De asemenea, puteți utiliza comanda UseModule, care vă permite să afișați toate elementele vizibile ale modulelor în spațiul curent. Acțiunea sa este anulată de comanda UnuseModule. Trebuie remarcat faptul că este posibilă afișarea elementelor vizibile ale mai multor module în același timp, cu condiția să nu existe un conflict de nume. Să presupunem că proiectul are module cu numele x, y și z.
UseModule x UseModule y ; Codul. Utilizați Modulul z ; Mai mult cod. UnuseModule y ; Mai mult cod. UnuseModule x UnuseModule zAcest exemplu arată că este posibilă maparea mai multor module la spațiul curent și, de asemenea, că ordinea în care elementele modulului sunt afișate și anulate nu este importantă.
În limbajele de programare fără suport nativ pentru spațiile de nume, spațiile pot fi emulate printr-o extensie folosind convențiile de denumire a identificatorului . De exemplu, bibliotecile C , cum ar fi Libpng , folosesc adesea un prefix fix pentru toate funcțiile și variabilele ca parte a front-end-ului lor. Libpng acceptă identificatori externi, cum ar fi:
png_create_write_struct png_get_signature png_read_row png_set_invalidAcest lucru oferă o garanție rezonabilă că identificatorii vor fi unici și, prin urmare, pot fi utilizați în programe mari fără teama de coliziuni ale numelor de identificare .
Dezavantajele emulării spațiului de nume includ :