Espacio de nombres ( eng. namespace ): algún conjunto , lo que significa un modelo, almacenamiento abstracto o entorno creado para la agrupación lógica de identificadores únicos (es decir, nombres).
Un identificador definido en un espacio de nombres está asociado con ese espacio de nombres . El mismo identificador se puede definir de forma independiente en varios espacios. Por lo tanto, un valor asociado con un identificador definido en un espacio de nombres puede o no tener el mismo valor que el mismo identificador definido en otro espacio de nombres. Los lenguajes conscientes del espacio de nombres definen reglas que indican a qué espacio de nombres pertenece un identificador (es decir, su definición).
Por ejemplo, Andrey trabaja en la empresa X, y su ID (abreviado del identificador inglés - identificador) como empleado es 123. Oleg trabaja en la empresa Y, y su ID también es 123. Lo único (desde el punto de vista de un determinado sistema de contabilidad), gracias a lo que Andrey y Oleg se pueden distinguir con identificaciones coincidentes es su pertenencia a diferentes empresas. La diferencia entre empresas en este caso es un sistema de diferentes espacios de nombres (una empresa - un espacio). La presencia de dos empleados en una empresa con el mismo DNI presenta grandes problemas a la hora de utilizarlos, por ejemplo, será muy difícil determinar el empleado al que va destinado este cheque a partir de una nómina que indicará un empleado con DNI 123.
En bases de datos grandes, puede haber cientos o miles de identificadores. Los espacios de nombres (o estructuras similares ) proporcionan un mecanismo para ocultar identificadores locales. Su significado es agrupar identificadores relacionados lógicamente en sus respectivos espacios de nombres, lo que hace que el sistema sea modular . También se puede limitar la visibilidad de las variables especificando su clase de almacenamiento .
Los sistemas operativos , muchos lenguajes de programación modernos admiten su propio modelo de espacio de nombres: utilizan directorios (o carpetas) como modelo de espacio de nombres. Esto permite que existan dos archivos con el mismo nombre (siempre y cuando estén en directorios diferentes). En algunos lenguajes de programación (por ejemplo , C++ , Python ), los identificadores de nombres de espacio están asociados a los espacios correspondientes. Por lo tanto, en estos lenguajes, los espacios de nombres pueden anidarse unos dentro de otros, formando un árbol de espacios de nombres. La raíz de dicho árbol se denomina espacio de nombres global .
En los lenguajes de programación, una de las formas de especificar el límite del espacio de nombres puede ser usar el llamado. alcance _
El espacio de nombres está definido por un bloque de instrucciones:
espacio de nombres foo { barra interna ; }Dentro de este bloque, los identificadores se pueden llamar exactamente como fueron declarados. Pero fuera del bloque, el nombre del espacio de nombres debe especificarse antes del identificador. Por ejemplo, fuera namespace foodel identificador bardebe especificarse como foo::bar. C++ contiene algunas otras construcciones que hacen que estos requisitos sean opcionales. Entonces, al agregar una línea
usando el espacio de nombres foo ;código, foo::ya no necesita especificar un prefijo. Otro ejemplo:
espacio de nombres Namespace12 { int foo = 0 ; } función vacía1 ( ) { utilizando el espacio de nombres Namespace12 ; // ahora todos los nombres del espacio de nombres Namespace12 serán visibles aquí sin prefijos adicionales ++ foo ; } función vacía2 ( ) { // y aquí se debe especificar el nombre: Namespace12 :: foo = 42 ; }Se supone que el código no declarado explícitamente en el espacio de nombres se declara en el espacio de nombres global.
La resolución del espacio de nombres en C++ es jerárquica. Esto significa que en un espacio de nombres hipotético еда::суп, el identificador курицаrepresentará еда::суп::курица(si existe el espacio). Si no existe, apunta a еда::курица(si existe ese espacio). Si este espacio tampoco existe, entonces se курицаrefiere a un identificador en el espacio global.
Los espacios de nombres se utilizan a menudo en C++ para evitar colisiones de nombres .
espacio de nombres { en un ; vacío f () { /*...*/ } int g () { /*...*/ } }No puede acceder a un miembro de un espacio de nombres anónimo desde una unidad de traducción desde otra unidad.
Aunque los espacios de nombres se usan ampliamente en el código moderno, gran parte del código antiguo no tiene estas características. Por ejemplo, toda la biblioteca estándar de C++ se define dentro namespace stdde , pero antes de la estandarización, muchos componentes se definían originalmente en el espacio global.
También puede hacer visible no todo el espacio, sino nombres individuales dentro de él, por ejemplo:
espacio de nombres foo { barra interna ; int somelse ; } int principal () { usando foo :: bar ; //Hace que solo la barra sea visible, ¡algunas veces invisible! devolver 0 ; }La idea de los espacios de nombres está plasmada en los paquetes de Java . Todo el código se define dentro de un paquete y el paquete no necesita un nombre explícito. El código de otros paquetes está disponible anteponiendo el nombre del paquete con el identificador correspondiente, por ejemplo, una clase Stringen un paquete java.langse puede llamar como java.lang.String(esto se conoce como un nombre de clase completamente calificado ). Al igual que en C++, Java proporciona una construcción que hace que la especificación del nombre del paquete ( import) sea opcional. Sin embargo, algunas características (como la reflexión ) requieren que el programador use el nombre completo.
A diferencia de C++, los espacios de nombres de Java no están ordenados jerárquicamente debido a la sintaxis del propio lenguaje. Sin embargo, los paquetes se nombran en un estilo jerárquico. Por ejemplo, todos los paquetes que comienzan con javason parte de la plataforma Java : el paquete java.langcontiene las clases base del lenguaje y java.lang.reflectcontiene las clases base específicas de la reflexión (reflejo).
En Java (así como en Ada , C# y otros lenguajes), los espacios de nombres/paquetes reflejan las categorías semánticas del código. Por ejemplo, en C# namespace Systemcontiene código que implementa el sistema ( plataforma .NET ). Cómo se definen exactamente estas categorías y qué tan profunda es la jerarquía depende del idioma en sí.
AlcanceUna función y una clase se pueden definir como un espacio de nombres implícito, íntimamente relacionado con la visibilidad, la accesibilidad y la vida útil del objeto .
Hay espacios de nombres en el lenguaje C#, el uso es similar a C++.
En Python, la idea de espacios de nombres se implementa en módulos. (Igual que en los paquetes de Java)
A pesar de la falta de soporte formal para los espacios de nombres, son fáciles de implementar utilizando el concepto de objeto del lenguaje:
var NameSpace_1 = {}; var NameSpace_2 = nuevo objeto (); //dos espacios de nombres Espacio de nombres_1 . a = 100 _ NameSpace_2 . a = "Fresa" ; // Variables a - cada una tiene la suya with ( NameSpace_1 ) // Especifique el espacio de nombres predeterminado { a += 10 ; NameSpace_2 . un += un ; //La variable de un espacio de nombres NameSpace_2 será igual a "Strawberry110" }En XML , la especificación de espacios de nombres XML define la unicidad de los nombres de elementos y atributos en un documento, de forma similar a la función de los espacios de nombres en un lenguaje de programación. Con los espacios de nombres, los documentos XML pueden contener nombres de elementos o atributos de más de un diccionario 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:Persona rdf:about= "#JW" > …xmlns (Espacio de nombres XML) - Espacio de nombres XML. Se incluyen RDF (para crear un documento RDF ) , FOAF y RDF Schema ( formato de diseño RDF ).
FOAF es también el espacio de un documento RDF , por lo que su diseño se comprueba de acuerdo con el vocabulario (reglas, especificaciones ) de RDF .
Desde la versión 5.3.0, PHP introdujo el concepto de espacio de nombres.
<?php espacio de nombres mi\nombre ; // definir un nuevo espacio de nombres class MiClase {} function mifuncion () {} const MYCONST = 1 ; $a = nueva MiClase ; // llamar dentro de mi\espacio de nombres $c = new \mi\nombre\MiClase ; // usar el nombre completo, incluido el nombre del espacio de nombres $d = new \globalClass ; // llamando a una clase desde el espacio de nombres global ?>Un punto importante. La directiva de espacio de nombres debe ser la primera línea de código del archivo. La excepción es la palabra clave declare, que puede preceder a la directiva de espacio de nombres. Incluso la salida HTML antes de la primera construcción "<?php" no está permitida.
La descripción de la sintaxis se encuentra en el sitio web oficial del proyecto PHP [1] .
La sintaxis estándar de Common Lisp tiene espacios de nombres de tabla implementados a través del sistema de paquetes [2] . Para usar un identificador (símbolo), debe especificar su nombre completo: nombre del paquete, dos puntos y el nombre del símbolo mismo [3] .
Allegro Common Lisp implementa una extensión Common Lisp no estándar: espacios de nombres jerárquicos, en los que los paquetes están separados por un punto en el estilo Java , y el identificador de los paquetes está separado por dos puntos. También es posible referirse a nodos adyacentes en la jerarquía del espacio de nombres especificando rutas relativas a través de dos puntos [4] . Los espacios de nombres en Common Lisp son dinámicos: se crean, completan y destruyen durante la ejecución del programa. , aunque se utiliza principalmente la forma declarativa de su descripción utilizando la forma defpackage[5] .
En PureBasic 5.20 , se introdujo la compatibilidad con espacios de nombres, implementada como módulos. El espacio de nombres está definido por el bloque de comandos Module y EndModule y no depende de la ubicación en los archivos de origen. Esto significa que en un archivo puede haber varios módulos, o viceversa: el código del módulo se puede dividir en varios archivos. De forma predeterminada, todo el espacio del módulo está oculto y, para que sus elementos individuales sean visibles, deben declararse en un bloque especial de comandos DeclareModule / EndDeclareModule. Cualquier cosa no declarada en este bloque no está disponible fuera del módulo, y el intentar acceder resultará en un mensaje de infracción de acceso del compilador.
DeclareModule Count x = 0 ; Elementos públicos Declarar contador () EndDeclareModule Recuento de módulos y = 0 _ Elementos privados Contador Procedimiento () y + 1 ProcedimientoRetorno y FinalizarProcedimiento EndModule Cuenta: : x = 10 ; Escribir un número en una variable (por ejemplo). Recuento de depuración :: Contador () ; Llamar a un procedimiento utilizando el nombre del módulo. Recuento de módulos de uso ; Asignación de un módulo al espacio actual. Contador de depuración () ; Acceso a elementos públicos (Public) sin especificar el nombre del módulo. UnuseModule Recuento ; Cancele la acción UseModule.Para acceder a los elementos del módulo desde otro módulo o espacio global, debe especificar el nombre del módulo y su elemento, por ejemplo: Count::x. También puede usar el comando UseModule, que le permite mostrar todos los elementos del módulo visibles en el espacio actual. Su acción es cancelada por el comando UnuseModule. Cabe señalar que es posible mostrar los elementos visibles de varios módulos al mismo tiempo, siempre que no haya conflicto de nombres. Digamos que el proyecto tiene módulos con los nombres x, y y z.
UsarMódulo x UsarMódulo y ; El código. Módulo de uso z ; Más código. UnuseModule y ; Más código. UnuseModule x UnuseModule zEste ejemplo muestra que es posible asignar varios módulos al espacio actual y que el orden en que se muestran y cancelan los elementos del módulo no es importante.
En lenguajes de programación sin soporte nativo para espacios de nombres, los espacios pueden ser emulados por una extensión usando convenciones de nomenclatura de identificadores . Por ejemplo, las bibliotecas C como Libpng a menudo usan un prefijo fijo para todas las funciones y variables como parte de su interfaz. Libpng admite identificadores externos como:
png_create_write_struct png_get_firma png_read_row png_set_inválidoEsto brinda una garantía razonable de que los identificadores serán únicos y, por lo tanto, se pueden usar en programas grandes sin temor a colisiones de nombres de identificadores .
Las desventajas de la emulación de espacio de nombres incluyen :