Namnutrymme

Inom databehandling är ett namnutrymme en uppsättning tecken ( namn ) som används för att identifiera och referera till objekt av olika slag. Ett namnområde säkerställer att alla en given uppsättning objekt har unika namn så att de lätt kan identifieras .

Namnutrymmen är vanligtvis strukturerade som hierarkier för att tillåta återanvändning av namn i olika sammanhang. Som en analogi, överväg ett system för namngivning av personer där varje person har ett förnamn, såväl som ett efternamn som delas med sina släktingar. Om förnamnen på familjemedlemmar endast är unika inom varje familj, kan varje person identifieras unikt genom kombinationen av förnamn och efternamn; det finns bara en Jane Doe, även om det kan finnas många Janes. Inom namnutrymmet för familjen Doe räcker bara "Jane" för att entydigt beteckna denna person, medan det fullständiga namnet måste användas inom det "globala" namnutrymmet för alla människor.

Framträdande exempel på namnområden inkluderar filsystem , som tilldelar namn till filer. Vissa programmeringsspråk organiserar sina variabler och subrutiner i namnrymder. Datornätverk och distribuerade system tilldelar namn till resurser, som datorer, skrivare, webbplatser och fjärrfiler. Operativsystem kan partitionera kärnresurser med isolerade namnområden för att stödja virtualiseringsbehållare .

På liknande sätt organiserar hierarkiska filsystem filer i kataloger. Varje katalog är ett separat namnutrymme, så att katalogerna "brev" och "fakturor" båda kan innehålla en fil "to_jane".

Inom datorprogrammering används namnutrymmen vanligtvis i syfte att gruppera symboler och identifierare runt en viss funktionalitet och för att undvika namnkollisioner mellan flera identifierare som delar samma namn.

I nätverk organiserar domännamnssystemet webbplatser (och andra resurser) i hierarkiska namnområden .

Namnkonflikter

Elementnamn definieras av utvecklaren. Detta resulterar ofta i en konflikt när man försöker blanda XML-dokument från olika XML-applikationer.

Denna XML innehåller HTML-tabellinformation :


    
        
        
    
 <table>  <tr>  <td>  Äpplen  </td>  <td>  Apelsiner  </td>  </tr>  </table> 

Denna XML innehåller information om ett bord (dvs en möbel):


    
    
    
 <table>  <name>  Mahogny Soffbord  </name>  <width>  80  </width>  <length>  120  </length>  </table> 

Om dessa XML-fragment lades ihop skulle det uppstå en namnkonflikt. Båda innehåller ett <table>...</table> -element, men elementen har olika innehåll och betydelse.

En XML-tolkare vet inte hur man hanterar dessa skillnader.

Lösning via prefix

Namnkonflikter i XML kan enkelt undvikas med ett namnprefix.

Följande XML skiljer mellan information om HTML-tabellen och möbler genom att prefixet "h" och "f" i början av elementen.


    
        
        
    



    
    
    
 <h:table>  <h:tr>  <h:td>  Äpplen  </h:td>  <h:td>  Apelsiner  </h:td>  </h:tr>  </h:table>  <f:table >  <f:name>  Soffbord i mahogny  </f:name>  <f:width>  80  </f:width>  <f:length>  120  </f:length>  </f:table> 

Namnsystem

Ett namn i ett namnområde består av ett namnområdesnamn och ett lokalt namn. Namnområdets namn används vanligtvis som ett prefix till det lokala namnet.

I utökad Backus-Naur-form :

namn = separator

När lokala namn används av sig själva, används namnupplösning för att bestämma vilket (om något) särskilt namn som anspelas på med något särskilt lokalt namn.

Exempel

Exempel på namn i ett namnutrymme
Sammanhang namn Namnområdets namn Lokalt namn
Väg /home/user/readme.txt /hem/användare (katalog) readme.txt (filnamn)
Domän namn www.exempel.com example.com (domännamn) www (bladdomännamn)
C++ std::array std (C++ namnutrymme) array (struktur)
UN/LOCODE US NYC USA (land eller territorium) NYC (ort)
XML
xmlns:xhtml=" http://www.w3.org/1999/xhtml " <xhtml:body>
xhtml (tidigare deklarerade XML-namnrymden xhtml=" http://www.w3.org/1999/xhtml ") kropp (element)
Perl $DBI::errstr $DBI (Perl-modul) errstr (variabel)
Java java.util.Datum java.util (Java namnutrymme) Datum (klass)
Uniform Resource Name (URN) urn:nbn:fi-fe19991055 urn:nbn (National Bibliography Numbers) fi-fe19991055
Handtagssystem 10.1000/182 10 (hantera namngivningsmyndighet) 1000/182 (lokalt namn på hanteraren)
Digital objektidentifierare 10.1000/182 10 1000 (förlag) 182 (publikation)
MAC-adress 01-23-45-67-89-ab 01-23-45 ( organisatoriskt unik identifierare ) 67-89-ab (NIC-specifik)
PCI ID 1234 abcd 1234 (leverantörs-ID) abcd (enhets-ID)
USB VID/PID 2341 003f 2341 (leverantörs-ID) 003f (produkt-ID)
SPARQL dbr: Sydney dbr (tidigare deklarerad ontologi, t.ex. genom att ange @prefix dbr: < http://dbpedia.org/resource/ > ) Sydney

Delegation

Delegering av ansvar mellan parter är viktigt i verkliga tillämpningar, såsom strukturen på World Wide Web. Namnutrymmen tillåter delegering av identifierartilldelning till flera namnutgivande organisationer med bibehållen global unikhet. En central registreringsmyndighet registrerar de tilldelade namnutrymmesnamnen . Varje namnområdesnamn tilldelas en organisation som därefter ansvarar för tilldelningen av namn i deras tilldelade namnområde. Denna organisation kan vara en namnutgivande organisation som själva tilldelar namnen , eller en annan registreringsmyndighet som vidare delegerar delar av sitt namnområde till olika organisationer.

Hierarki

Ett namnschema som tillåter underdelegering av namnområden till tredje part är ett hierarkiskt namnområde .

En hierarki är rekursiv om syntaxen för namnområdets namn är densamma för varje underdelegering. Ett exempel på en rekursiv hierarki är domännamnssystemet .

Ett exempel på en icke-rekursiv hierarki är Uniform Resource Name som representerar ett IANA-nummer ( Internet Assigned Numbers Authority) .

Hierarkisk namnområdesuppdelning för urn:isbn:978-3-16-148410-0 , en identifierare för boken The Logic of Scientific Discovery av Karl Popper, 10:e upplagan.
Register Registrator Exempelidentifierare Namnområdets namn Namnutrymme
Uniform Resource Name (URN) Internet Assigned Numbers Authority urn:isbn:978-3-16-148410-0 urna Formellt URN-namnområde
Formellt URN-namnområde Internet Assigned Numbers Authority urn:isbn:978-3-16-148410-0 ISBN Internationella standardboknummer som enhetliga resursnamn
Internationellt artikelnummer (EAN) GS1 978-3-16-148410-0 978 Bokland
International Standard Book Number (ISBN) Internationella ISBN-byrån 3-16-148410-X 3 tysktalande länder
Tysk förlagskod Agentur für Buchmarktstandards 3-16-148410-X 16 Mohr Siebeck

Namnutrymme kontra omfattning

Ett namnområdesnamn kan ge sammanhang ( omfattning inom datavetenskap) till ett namn, och termerna används ibland omväxlande. Kontexten för ett namn kan dock också tillhandahållas av andra faktorer, såsom platsen där det förekommer eller syntaxen för namnet.

Exempel på namnsystem med lokal och global räckvidd, och med och utan namnutrymmen
Utan namnutrymme Med ett namnutrymme
Lokal omfattning Fordons registreringsskylt Filsystemhierarkistandard
Globalt omfång Universellt unik identifierare domännamnssystem

I programmeringsspråk

För många programmeringsspråk är namnutrymmet ett sammanhang för deras identifierare . I ett operativsystem är ett exempel på namnutrymme en katalog. Varje namn i en katalog identifierar unikt en fil eller underkatalog.

Som regel kan namn i ett namnutrymme inte ha mer än en betydelse; det vill säga att olika betydelser inte kan dela samma namn i samma namnutrymme. Ett namnområde kallas också ett sammanhang eftersom samma namn i olika namnutrymmen kan ha olika betydelser, var och en lämplig för dess namnområde.

Följande är andra egenskaper hos namnutrymmen:

Förutom dess abstrakta språktekniska användning som beskrivs ovan, har vissa språk ett specifikt nyckelord som används för explicit namnområdeskontroll, bland annat. Nedan är ett exempel på ett namnområde i C++:

 



 
 

  
       


  
       


  
       
          
          
          
 #include  <iostream>  // Så här tar man in ett namn i det aktuella omfånget. I det här fallet är det   // som för dem in i global omfattning.  använder  std  ::  cout  ;  använder  std  ::  endl  ;  namnutrymme  box1  {  int  box_side  =  4  ;  }  namnutrymme  box2  {  int  box_side  =  12  ;  }  int  main  ()  {  int  box_side  =  42  ;  cout  <<  box1  ::  box_side  <<  endl  ;  // Utgångar 4.  cout  <<  box2  ::  box_side  <<  endl  ;  // Utgångar 12.  cout  <<  box_side  <<  endl  ;  // Utgångar 42.  } 

Datavetenskapliga överväganden

Ett namnområde inom datavetenskap (ibland även kallat ett namnomfång ) är en abstrakt behållare eller miljö skapad för att hålla en logisk gruppering av unika identifierare eller symboler (dvs. namn). En identifierare som definieras i ett namnområde associeras endast med det namnområdet. Samma identifierare kan definieras oberoende av varandra i flera namnområden. Det vill säga, en identifierare som definieras i ett namnområde kan ha eller inte ha samma betydelse som samma identifierare som definieras i ett annat namnområde. Språk som stöder namnområden anger reglerna som bestämmer vilket namnområde en identifierare (inte dess definition) tillhör.

Detta koncept kan illustreras med en analogi. Föreställ dig att två företag, X och Y, tilldelar varsin id-nummer till sina anställda. X ska inte ha två anställda med samma ID-nummer, och likaså för Y; men det är inget problem att samma ID-nummer används på båda företagen. Till exempel, om Bill arbetar för företag X och Jane arbetar för företag Y, är det inte ett problem för var och en av dem att vara anställd #123. I denna analogi är ID-numret identifieraren och företaget fungerar som namnområdet. Det orsakar inga problem för samma identifierare att identifiera en annan person i varje namnområde.

I stora datorprogram eller dokument är det vanligt att ha hundratals eller tusentals identifierare. Namnutrymmen (eller en liknande teknik, se Emulera namnutrymmen ) tillhandahåller en mekanism för att dölja lokala identifierare. De tillhandahåller ett sätt att gruppera logiskt relaterade identifierare i motsvarande namnutrymmen, vilket gör systemet mer modulärt .

Datalagringsenheter och många moderna programmeringsspråk stöder namnutrymmen. Lagringsenheter använder kataloger (eller mappar) som namnutrymmen. Detta gör att två filer med samma namn kan lagras på enheten så länge som de lagras i olika kataloger. I vissa programmeringsspråk (t.ex. C++ , Python ) är identifierarna som namnger namnområden i sig associerade med ett omslutande namnområde. På dessa språk kan alltså namnområden kapsla och bilda ett namnområdesträd . I roten av detta träd finns det namnlösa globala namnutrymmet .

Använd på vanliga språk

C

Det är möjligt att använda anonyma strukturer som namnutrymmen i C sedan C99 .


      
       


  
     
       
      


  
     
       
 


 
 

 
      
     
 // helper.c  static  int  _add  (  int  a  ,  int  b  )  {  retur  a  +  b  ;  }  const  struct  {  double  pi  ;  int  (  *  addera  )  (  int  ,  int  );  }  hjälpare  =  {  3.14  ,  _add  };  // helper.h  const  struct  {  double  pi  ;  int  (  *  addera  )  (  int  ,  int  );  }  hjälpare  ;  // main.c  #include  <stdio.h>  #include  "helper.h"  int  main  (){  printf  (  "3 + 2 = %d  \n  "  ,  helper  .  add  (  3  ,  2  ));  printf  (  "pi är %f  \n  "  ,  hjälpare  .  pi  );  } 
C++

I C++ definieras ett namnområde med ett namnområdesblock.

  
     
 namnutrymme  abc  {  int  bar  ;  } 

Inom detta block kan identifierare användas exakt som de deklareras. Utanför detta block måste namnutrymmesspecifikationen ha prefix. , utanför namnrymden abc måste bar skrivas abc::bar för att komma åt. C++ innehåller en annan konstruktion som gör denna utförlighet onödig. Genom att lägga till raden

   använder  namnutrymme  abc  ; 

till en kodbit behövs inte längre prefixet abc:: .

Identifierare som inte är explicit deklarerade inom ett namnområde anses vara i det globala namnområdet.

  int  foo  ; 

Dessa identifierare kan användas exakt som de deklareras, eller, eftersom det globala namnområdet är namnlöst, kan namnområdesspecifikationen :: ha prefix. Till exempel foo också skrivas ::foo .

Namnutrymmesupplösningen i C++ är hierarkisk. Det betyder att inom det hypotetiska namnområdet mat::soppa hänvisar identifieraren kyckling till mat::soppa::kyckling . Om mat::soppa::kyckling inte finns så avser det mat::kyckling . Om varken mat::soppa::kyckling eller mat::kyckling finns, hänvisar kyckling till ::kyckling , en identifierare i det globala namnområdet.

Namnutrymmen i C++ används oftast för att undvika namnkollisioner . Även om namnrymder används flitigt i nyare C++-kod, använder de flesta äldre koder inte den här funktionen eftersom den inte fanns i tidiga versioner av språket. Till exempel är hela C++ Standard Library definierat inom namnområdet std , men innan standardiseringen fanns många komponenter ursprungligen i det globala namnområdet. En programmerare kan infoga användningsdirektivet för att kringgå krav på namnutrymmesupplösning och få bakåtkompatibilitet med äldre kod som förväntar sig att alla identifierare finns i det globala namnområdet. Användningen av användningsdirektivet av andra skäl än bakåtkompatibilitet (t.ex. bekvämlighet) anses strida mot god uppförandekod.

Java

I Java är idén med ett namnområde inkorporerat i Java-paket . All kod tillhör ett paket, även om det paketet inte behöver namnges uttryckligen. Kod från andra paket nås genom att prefixet paketnamnet före lämplig identifierare, till exempel klass String i paketet java.lang kan refereras till som java.lang.String (detta är känt som det fullständiga klassnamnet ). Precis som C++ erbjuder Java en konstruktion som gör det onödigt att skriva paketnamnet ( import ). Vissa funktioner (som reflektion ) kräver dock att programmeraren använder det fullständiga namnet.

Till skillnad från C++ är namnutrymmen i Java inte hierarkiska när det gäller språkets syntax. Emellertid namnges paket på ett hierarkiskt sätt. Till exempel är alla paket som börjar med java en del av Java-plattformen — paketet java.lang innehåller klasser som är kärnan i språket, och java.lang.reflect innehåller kärnklasser specifikt relaterade till reflektion.

I Java (och Ada , C# och andra) uttrycker namnutrymmen/paket semantiska kodkategorier. Till exempel, i C#, namnområde System kod som tillhandahålls av systemet ( .NET Framework) . Hur specifika dessa kategorier är och hur djupt hierarkierna går skiljer sig från språk till språk.

Funktions- och klassomfång kan ses som implicita namnutrymmen som är oupplösligt kopplade till synlighet, tillgänglighet och objektlivslängd .

C#

Namnutrymmen används flitigt i C#-språket. Alla .NET Framework-klasser är organiserade i namnutrymmen, för att användas tydligare och för att undvika kaos. Dessutom används anpassade namnområden flitigt av programmerare, både för att organisera sitt arbete och för att undvika namnkollisioner . När man refererar till en klass bör man ange antingen dess fullständiga namn, vilket betyder namnutrymme följt av klassnamnet,


    System  .  Konsol  .  WriteLine  (  "Hej världen!"  );  int  i  =  System  .  Konvertera  .  ToInt32  (  "123"  ); 

eller lägg till ett användande uttalande. Detta eliminerar behovet av att nämna det fullständiga namnet på alla klasser i det namnområdet.

 


    använder  System  ;  Konsol  .  WriteLine  (  "Hej världen!"  );  int  i  =  Konvertera  .  ToInt32  (  "123"  ); 

I exemplen ovan är System ett namnområde, och Console och Convert är klasser som definieras inom System .

Pytonorm

I Python definieras namnrymder av de individuella modulerna, och eftersom moduler kan ingå i hierarkiska paket är namnrymder också hierarkiska. I allmänhet när en modul importeras så definieras namnen som definieras i modulen via den modulens namnområde och nås in från de anropande modulerna genom att använda det fullständiga namnet.


 



   # anta att modulea definierar två funktioner: func1() och func2() och en klass: Class1  import  Modulea  Modulea  .  func1  ()  Modulea  .  func2  ()  a  =  Modulea  .  Klass 1  () 

Från ... import ...- satsen kan användas för att infoga de relevanta namnen direkt i den anropande modulens namnområde, och dessa namn kan nås från den anropande modulen utan det kvalificerade namnet:


   


 
    # anta att Modulea definierar två funktioner : func1() och func2() och en klass : Class1  from  Modulea  import  func1  func1  ()  func2  ()  # detta kommer att misslyckas som ett odefinierat namn, liksom det fullständiga namnet Modulea.func2()  a  =  Class1  ()  # detta kommer att misslyckas som ett odefinierat namn, liksom det fullständiga namnet Modulea.Class1() 

Eftersom detta direkt importerar namn (utan kvalifikationer) kan det skriva över befintliga namn utan varningar.

En speciell form av uttalandet är från ... import * som importerar alla namn definierade i det namngivna paketet direkt i den anropande modulens namnområde. Användning av denna form av import, även om den stöds inom språket, avråds i allmänhet eftersom det förorenar namnutrymmet för den anropande modulen och kommer att göra att redan definierade namn skrivs över i fallet med namnkrockar.

Python stöder också import x som y som ett sätt att tillhandahålla ett alias eller alternativt namn för användning av den anropande modulen:

   

   importera  numpy  som  np  a  =  np  .  arange  (  1000  ) 
XML-namnutrymme

I XML gör XML-namnutrymmesspecifikationen att namnen på element och attribut i ett XML-dokument kan vara unika, på samma sätt som namnområdenas roll i programmeringsspråk. Med XML-namnrymder kan XML-dokument innehålla element- eller attributnamn från mer än ett XML-ordförråd.

PHP

Namnutrymmen introducerades i PHP från version 5.3 och framåt. Namnkollision mellan klasser, funktioner och variabler kan undvikas. I PHP definieras ett namnområde med ett namnområdesblock.



 

 

       
    
         
    

       
    
         
    
 # Filen phpstar/foobar.php  namnutrymme  phpstar  ;  class  FooBar  {  public  function  foo  ()  :  void  {  echo  'Hej världen, från function foo'  ;  }  public  function  bar  ()  :  void  {  echo  'Hello world, from function bar'  ;  }  } 

Vi kan referera till ett PHP-namnområde på följande olika sätt:




 


   


 
   


   
   



 # Fil index.php  # Inkludera filen  include  "phpstar/foobar.php"  ;  # Alternativ 1: direkt prefix klassnamnet med namnutrymmet  $obj_foobar  =  new  \phpstar\FooBar (  );  # Alternativ 2: importera namnutrymmet  med  phpstar\FooBar  ;  $obj_foobar  =  ny  FooBar  ();  # Alternativ 2a: importera & alias namnområdet  använd  phpstar\FooBar  som  FB  ;  $obj_foobar  =  ny  FB  ();  # Få tillgång till egenskaperna och metoderna med vanliga sätt  $obj_foobar  ->  foo  ();  $obj_foobar  ->  bar  (); 

Emulerar namnutrymmen

I programmeringsspråk som saknar språkstöd för namnutrymmen, kan namnområden emuleras till viss del genom att använda en namnkonvention för identifierare . Till exempel C- bibliotek som libpng ofta ett fast prefix för alla funktioner och variabler som är en del av deras exponerade gränssnitt. Libpng avslöjar identifierare som:

png_create_write_struct png_get_signature png_read_row png_set_invalid

Denna namnkonvention ger rimlig säkerhet att identifierarna är unika och därför kan användas i större program utan namnkollisioner . På samma sätt reserverar många paket som ursprungligen skrevs i Fortran (t.ex. BLAS , LAPACK ) de första bokstäverna i en funktions namn för att indikera vilken grupp den tillhör.

Denna teknik har flera nackdelar:

  • Den skalas inte bra till kapslade namnområden; identifierare blir för långa eftersom all användning av identifierarna måste vara fullständigt namnområdeskvalificerade .
  • Individer eller organisationer kan använda inkonsekventa namnkonventioner, vilket kan leda till oönskad förvirring.
  • Sammansatta eller "frågebaserade" operationer på grupper av identifierare, baserade på namnområdena där de deklareras, görs svårhanterliga eller omöjliga.
  • På språk med begränsad identifierarlängd begränsar användningen av prefix antalet tecken som kan användas för att identifiera vad funktionen gör. Detta är ett särskilt problem för paket som ursprungligen skrevs i FORTRAN 77 , som endast erbjöd 6 tecken per identifierare. Namnet på BLAS -funktionen DGEMM- funktionen indikerar till exempel att den fungerar på tal med dubbel precision ("D") och allmänna matriser ("GE"), och endast de två sista tecknen visar vad den faktiskt gör: matris-matrismultiplikation ("MM").

Det finns flera fördelar:

  • Inga speciella mjukvaruverktyg krävs för att hitta namn i källkodsfiler. Ett enkelt program som grep räcker.
  • Det finns inga namnkonflikter.
  • Det finns inget behov av namnmangling, och därmed inga potentiella inkompatibilitetsproblem.

Se även