Namespace ( eng. namespace ) - någon uppsättning , vilket betyder en modell, abstrakt lagring eller miljö skapad för den logiska grupperingen av unika identifierare (det vill säga namn).
En identifierare som definieras i ett namnområde är associerat med det namnområdet . Samma identifierare kan definieras oberoende av varandra i flera utrymmen. Således kan ett värde som är associerat med en identifierare definierad i ett namnområde ha samma värde som samma identifierare som definieras i ett annat namnområde. Namnutrymmesmedvetna språk definierar regler som indikerar vilket namnområde en identifierare tillhör (dvs dess definition).
Till exempel arbetar Andrey i företag X, och hans ID (förkortat från den engelska Identifier - identifierare) som anställd är 123. Oleg arbetar i företag Y, och hans ID är också 123. Det enda (från det att syn på ett visst redovisningssystem), tack vare vad Andrey och Oleg kan särskiljas med matchande ID är deras tillhörighet till olika företag. Skillnaden mellan företag i det här fallet är ett system med olika namnutrymmen (ett företag - ett utrymme). Närvaron av två anställda i ett företag med samma ID ger stora problem när man använder dem, till exempel kommer det att vara mycket svårt att avgöra vilken anställd som denna check är avsedd för från en lönecheck som kommer att indikera en anställd med ID 123.
I stora databaser kan det finnas hundratals eller tusentals identifierare. Namnutrymmen (eller liknande strukturer ) tillhandahåller en mekanism för att dölja lokala identifierare. Deras betydelse är att gruppera logiskt relaterade identifierare i sina respektive namnområden, vilket gör systemet modulärt . Att begränsa synligheten för variabler kan också göras genom att specificera dess lagringsklass .
Operativsystem , många moderna programmeringsspråk stöder sin egen namnområdesmodell: de använder kataloger (eller mappar) som en namnområdesmodell. Detta tillåter två filer med samma namn (så länge de finns i olika kataloger). I vissa programmeringsspråk (t.ex. C++ , Python ) är utrymmesnamnidentifierare i sig associerade med motsvarande mellanslag. På dessa språk kan därför namnrymder häckas inom varandra och bilda ett träd av namnutrymmen. Roten till ett sådant träd kallas det globala namnutrymmet .
I programmeringsspråk kan ett av sätten att ange namnutrymmesgränsen vara att använda den sk. omfattning .
Namnutrymmet definieras av ett block med instruktioner:
namnområde foo { int bar ; }Inom detta block kan identifierare anropas exakt som de deklarerades. Men utanför blocket måste namnområdets namn anges före identifieraren. Till exempel ska utanför namespace fooidentifieraren baranges som foo::bar. C++ innehåller några andra konstruktioner som gör dessa krav valfria. Så när du lägger till en rad
använder namnutrymme foo ;kod behöver du foo::inte längre ange ett prefix. Ett annat exempel:
namnområde Namnområde12 { int foo = 0 ; } void func1 () { använder namnutrymme Namnutrymme12 ; // nu kommer alla namn från namnområdet Namespace12 att synas här utan ytterligare prefix ++ foo ; } void func2 () { // och här måste namnet anges: Namespace12 :: foo = 42 ; }Kod som inte uttryckligen deklareras i namnområdet antas vara deklarerat i det globala namnområdet.
Namnutrymmesupplösningen i C++ är hierarkisk. Det betyder att i ett hypotetiskt namnområde еда::супkommer identifieraren курицаatt stå för еда::суп::курица(om utrymmet finns). Om det inte finns, så pekar det på еда::курица(om det utrymmet finns). Om detta utrymme inte heller existerar, курицаhänvisar det till en identifierare i det globala utrymmet.
Namnutrymmen används ofta i C++ för att undvika namnkollisioner .
namnutrymme { int a ; void f () { /*...*/ } int g () { /*...*/ } }Du kan inte komma åt en medlem i ett anonymt namnområde från en översättningsenhet från en annan enhet.
Även om namnrymder används i stor utsträckning i modern kod, har mycket av den äldre koden inte dessa funktioner. Till exempel är hela C++-standardbiblioteket definierat inom namespace std, men före standardiseringen definierades ursprungligen många komponenter i det globala rummet.
Du kan också synliggöra inte hela utrymmet, utan enskilda namn inom det, till exempel:
namnområde foo { int bar ; int något annat ; } int main () { använder foo :: bar ; //Gör bara bar synlig, någon annan osynlig! returnera 0 ; }Idén med namnutrymmen finns i Java-paket . All kod definieras i ett paket, och paketet behöver inte ett explicit namn. Kod från andra paket är tillgänglig genom att prefixet paketnamnet med motsvarande identifierare, till exempel kan en klass Stringi ett paket java.langkallas som java.lang.String(detta är känt som ett fullt kvalificerat klassnamn ). Precis som i C++ tillhandahåller Java en konstruktion som gör det valfritt att ange paketnamnet ( import). Vissa funktioner (som reflektion ) kräver dock att programmeraren använder det fullständiga namnet.
Till skillnad från C++ är Java-namnrymder inte hierarkiskt ordnade på grund av själva språkets syntax. Emellertid är paket namngivna i en hierarkisk stil. Till exempel är alla paket som börjar med javaen del av Java-plattformen - paketet java.langinnehåller basklasserna för språket, och java.lang.reflectinnehåller basklasserna som är specifika för reflektion (reflektion).
I Java (liksom i Ada , C# och andra språk) återspeglar namnrymder/paket de semantiska kategorierna av kod. Till exempel i C# namespace Systeminnehåller kod som implementeras av systemet ( .NET- plattform ). Hur exakt dessa kategorier definieras och hur djup hierarkin är beror på språket i sig.
OmfattningEn funktion och en klass kan definieras som ett implicit namnområde, intrikat relaterat till objektets synlighet, tillgänglighet och livslängd .
Det finns namnutrymmen i C#-språket, användningen liknar C++.
I Python implementeras idén med namnutrymmen i moduler. (Samma som i Java-paket)
Trots bristen på formellt stöd för namnutrymmen är de lätta att implementera med hjälp av språkets objektkoncept:
var NameSpace_1 = {}; var NameSpace_2 = nytt objekt (); //två namnutrymmen NameSpace_1 . a = 100 _ NameSpace_2 . a = "Jordgubbe" ; // Variabler a - var och en har sin egen with ( NameSpace_1 ) // Ange standardnamnrymden { a += 10 ; NameSpace_2 . a += a ; //Variabel ett namnområde NameSpace_2 kommer att vara lika med "Strawberry110" }I XML definierar specifikationen av XML-namnrymder unikheten hos element- och attributnamn i ett dokument, liknande rollen för namnrymder i ett programmeringsspråk. Med namnrymder kan XML-dokument innehålla element- eller attributnamn från mer än en XML-ordbok.
<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-namnutrymme) - XML-namnutrymme. RDF (för att skapa ett RDF-dokument ) , FOAF och RDF - schema ( RDF-designformat ) ingår.
FOAF är också utrymmet för ett RDF- dokument, så dess design kontrolleras enligt vokabulären (regler, specifikationer ) för RDF .
Sedan version 5.3.0 har PHP introducerat konceptet med ett namnområde.
<?php namnutrymme mitt\namn ; // definiera ett nytt namnområde class MyClass {} function myfunction () {} const MYCONST = 1 ; $a = ny MinKlass ; // ring inuti mitt\namn utrymme $c = nytt \mitt\namn\MinKlass ; // använd fullständigt namn inklusive namnområdesnamn $d = new \globalClass ; // anropar en klass från det globala namnområdet ?>En viktig punkt. Namnutrymmesdirektivet måste vara den första kodraden i filen. Undantaget är nyckelordet declare, som kan föregå namnutrymmesdirektivet. Även HTML-utdata före den första "<?php"-konstruktionen är inte tillåten.
Syntaxbeskrivningen finns på PHP-projektets officiella webbplats [1] .
Standardsyntaxen för Common Lisp har tabellnamnrymder implementerade genom paketsystemet [2] . För att använda en identifierare (symbol) måste du ange dess fullständiga namn: paketnamn, kolon och namnet på själva symbolen [3] .
Allegro Common Lisp implementerar ett icke-standardiserat Common Lisp-tillägg - hierarkiska namnområden, där paket separeras med en punkt i Java -stilen och identifieraren från paketen separeras med ett kolon. Det är också möjligt att referera till intilliggande noder i namnrymdshierarkin genom att ange relativa sökvägar genom två punkter [4] . Namnområden i Common Lisp är dynamiska - de skapas, fylls i och förstörs under programkörning. , även om den deklarativa formen av deras beskrivning med hjälp av formuläret defpackage[5] huvudsakligen används .
I PureBasic 5.20 introducerades namnutrymmesstöd, implementerat som moduler. Namnutrymmet definieras av kommandoblocken Module och EndModule och beror inte på platsen i källfilerna. Det betyder att i en fil kan det finnas flera moduler, eller vice versa - modulkoden kan delas upp i flera filer. Som standard är hela modulutrymmet dolt, och för att synliggöra dess individuella element måste de deklareras i ett speciellt block med kommandon DeclareModule / EndDeclareModule. Allt som inte deklarerats i detta block är inte tillgängligt utanför modulen, och ett försök att få åtkomst kommer att resultera i ett meddelande om åtkomstbrott från kompilatorn.
DeclareModule Count x = 0 ; Offentliga element Declare Counter () EndDeclareModule Antal moduler y = 0 _ Privata inslag Motprocedur ( ) y + 1 ProcedurReturn y EndProcedure EndModule Antal: : x = 10 ; Att skriva ett tal till en variabel (till exempel). Debug Count :: Counter () ; Anropa en procedur med modulnamnet. UseModule Count ; Mappa en modul till det aktuella utrymmet. Debug Counter () ; Tillgång till offentliga (Public) element utan att ange modulnamnet. UnuseModule Count ; Avbryt UseModule-åtgärden.För att komma åt modulelement från en annan modul eller globalt utrymme måste du ange modulnamnet och dess element, till exempel: Count::x. Du kan också använda kommandot UseModule, som låter dig visa alla synliga modulelement i det aktuella utrymmet. Dess åtgärd avbryts av kommandot UnuseModule. Det bör noteras att det är möjligt att visa de synliga elementen i flera moduler samtidigt, förutsatt att det inte finns någon namnkonflikt. Låt oss säga att projektet har moduler med namnen x, y och z.
UseModule x UseModule y ; Koden. AnvändModul z ; Mer kod. UnuseModule y ; Mer kod. UnuseModule x UnuseModule zDetta exempel visar att det är möjligt att mappa flera moduler till det aktuella utrymmet, och även att ordningen i vilken modulelement visas och avbryts inte är viktig.
I programmeringsspråk utan inbyggt stöd för namnutrymmen kan utrymmen emuleras av en förlängning som använder identifierare namnkonventioner . Till exempel använder C - bibliotek som Libpng ofta ett fast prefix för alla funktioner och variabler som en del av deras gränssnitt. Libpng stöder externa identifierare som:
png_create_write_struct png_get_signature png_read_row png_set_invalidDetta ger en rimlig garanti för att identifierarna kommer att vara unika och därmed kan användas i stora program utan rädsla för identifierare namnkollisioner .
Nackdelarna med namnrymdsemulering inkluderar :