La documentación solo menciona tipos anidados, pero no está claro si se pueden usar como espacios de nombres. No he encontrado ninguna mención explícita de espacios de nombres.
Una búsqueda rápida de Ctrl-F en su iBook no muestra instancias de espacios de nombres ... ¿entonces voy con no?
Justin Niessner
1
No sé por qué esta pregunta está cerrada. Vi espacio de nombres de apertura en el lado izquierdo del icono de Swift, y todavía no puede encontrar ninguna mención de la documentación ...
eonil
No pude encontrar ninguna información sobre esto, Google me llevó a esta pregunta :). Quizás una de las sesiones de la WWDC arroje un poco más de luz sobre esto.
Zyphrax
También estoy esperando que alguien en la WWDC presente una buena explicación.
eonil
La respuesta de Eonil es correcta. Usas módulos en Xcode para separar tus clases.
Los espacios de nombres no son por archivo; son por objetivo (según la configuración de compilación "Nombre del módulo del producto"). Entonces terminarías con algo como esto:
importFrameworkAimportFrameworkBFrameworkA.foo()
Todas las declaraciones de Swift se consideran parte de algún módulo, por lo que incluso cuando dice " NSLog" (sí, todavía existe), obtiene lo que Swift considera " Foundation.NSLog".
El espacio de nombres está implícito en Swift, todas las clases (etc.) están implícitamente definidas por el módulo (destino de Xcode) en el que se encuentran. No se necesitan prefijos de clase
Parece ser muy diferente lo que he estado pensando.
Foros de Apple Dev ... ¡He visto tanta planta rodadora que no creerías!
Nicolas Miari
1
El enlace a los foros de desarrollo de Apple ahora está roto, y Apple no ha importado ese hilo al nuevo forums.developer.apple.comsitio de foros, desafortunadamente.
Dai
2
@Dai Parece que es por eso que debemos evitar los foros de Apple para preguntas y respuestas ... Pero a los miembros del equipo de desarrollo central no parece importarles mucho las SO. Que tragedia.
eonil
1
¿Qué quieres decir con planta rodadora?
Alexander Mills
148
Describiría el espacio de nombres de Swift como aspiracional; Se le ha dado mucha publicidad que no corresponde a ninguna realidad significativa sobre el terreno.
Por ejemplo, los videos de WWDC establecen que si un marco que está importando tiene una clase MyClass y su código tiene una clase MyClass, esos nombres no entran en conflicto porque el "cambio de nombre" les da diferentes nombres internos. En realidad, sin embargo, sí entran en conflicto, en el sentido de que MyClass de su propio código gana, y no puede especificar "No, no, me refiero a MyClass en el marco": decir TheFramework.MyClassque no funciona (el compilador sabe a qué se refiere , pero dice que no puede encontrar esa clase en el marco).
Mi experiencia es que Swift, por lo tanto, no tiene espacio de nombres en lo más mínimo. Al convertir una de mis aplicaciones de Objective-C a Swift, creé un marco incrustado porque era muy fácil y genial de hacer. Sin embargo, al importar el marco, se importan todas las cosas de Swift en el marco, por lo que, una vez más, solo hay un espacio de nombres y es global. Y no hay encabezados Swift, por lo que no puede ocultar ningún nombre.
EDITAR: en la semilla 3, esta característica ahora está comenzando a estar en línea, en el siguiente sentido: si su código principal contiene MyClass y su marco MyFramework contiene MyClass, el primero eclipsa al segundo de forma predeterminada, pero puede alcanzar el que está en el marco mediante el uso de la sintaxis MyFramework.MyClass. ¡Así, de hecho, tenemos los rudimentos de un espacio de nombres distinto!
EDITAR 2: ¡ en la semilla 4, ahora tenemos controles de acceso! Además, en una de mis aplicaciones tengo un marco incrustado y, por supuesto, todo estaba oculto de forma predeterminada y tuve que exponer todos los bits de la API pública explícitamente. Esta es una gran mejora.
Gracias por esta respuesta Funciona no solo con Frameworks, sino también con la Biblioteca estándar. Puede "sobrescribir" la matriz, por ejemplo. Entonces "Array" se refiere a su propia clase de Array personalizada, y el Array de la Biblioteca Estándar está disponible como "Swift.Array".
George
3
@George Y de manera similar para NSArray; si lo eclipsas, aún puedes referirte a él como Foundation.NSArray.
mate
1
Entonces, sin tener que clasificar la historia del pensamiento en los espacios de nombres en las versiones beta: ¿dónde está esta respuesta ahora?
Dan Rosenstark
1
@Yar como se indica en las ediciones. El nombre del módulo es un espacio de nombres opcional si hay ambigüedad, y ahora hay privacidad, por lo que los nombres de los módulos están ocultos a menos que se expongan y un nombre se pueda limitar a un archivo.
mate
2
Esto me ha estado molestando durante mucho tiempo, parece que cualquier proyecto Swift no debería usar un prefijo debido a lo que Apple afirma, sin embargo, en este momento todavía se requiere un prefijo, incluso con los modificadores de acceso. Si bien no entrará en conflicto con el paquete o las clases privadas en el marco de Apple, cualquier cosa declarada pública, por ejemplo String, si declara eso nuevamente, o cualquier clase nueva, terminará usando la suya, a menos que, por supuesto, tenga la costumbre de refiriéndose a todas las clases con su espacio de nombres ... no es bueno.
Oscar Gomez
19
Mientras experimentaba un poco con esto, terminé creando estas clases de "espacios de nombres" en sus propios archivos extendiendo el "paquete" raíz. No estoy seguro de si esto va en contra de las mejores prácticas o si tiene alguna implicación que yo sepa (?)
extensionPackageOne{classClass{var name:Stringinit(name:String){self.name = name
}}}
PackageTwoClass.swift
extensionPackageTwo{classClass{var name:Stringinit(name:String){self.name = name
}}}
Editar:
Me acabo de enterar de que crear "subpaquetes" en el código anterior no funcionará si se usan archivos separados. ¿Quizás alguien pueda insinuar por qué ese sería el caso?
No estoy seguro de lo que quieres decir con "prueba", pero seguí adelante y comencé a construir mi aplicación usando la técnica anterior y parece funcionar bien hasta ahora con la advertencia que agregué a mi entrada anterior. Lo estoy haciendo principalmente porque estoy acostumbrado a organizar mi código de esta manera en otros idiomas y agradecería que alguien con más conocimiento pudiera decirme que es una mala idea hasta que vaya demasiado lejos. :)
bWlrYWphdWhvbmVu
1
sigamos adelante ... esto es lo que queremos ... poder tener una misma clase de nombre en dos paquetes diferentes para poder existir y hacer referencia en consecuencia (más importante, archivos diferentes) y si no funciona, todo idea del espacio de nombres es una idea de fracaso ...
user2727195
¿Algún efecto secundario usando "struct" como una forma de hackear espacios de nombres?
Alex Nolasco
No es que me haya encontrado en lo que respecta al rendimiento. Xcode (6.1 GM) en algunos casos raros se queja de tipos no existentes, pero creo que este podría ser el caso cuando no se estructura un código como este también. Recientemente resolví un problema agregando todos los archivos a mi Test-target que no tiene ningún sentido pero resolvió el problema. :)
Todavía no estoy tan contento con la forma en que se hacen los espacios de nombres ... ¿qué pasa si tengo diez clases diferentes en un espacio de nombres, y además prefiero mantener las clases en sus archivos individuales, no quiero inflar una? file / struct con todas las clases, cualquier sugerencia de Kevin.
user2727195
2
Me pregunto por qué no pensaron incluir paquetes, eso es lo que necesitamos, no espacios de nombres, me refiero a mirar otros lenguajes de alto nivel como Java, C #, ActionScript, todos tienen paquetes, los espacios de nombres en este contexto no son nada diferentes de usar NS u otros prefijos para sus clases de proyecto
usuario2727195
1
No puedo evitar preguntarme si el uso de estructuras como una forma de hackear espacios de nombres puede causar problemas desconocidos.
Alex Nolasco
1
Esta es una buena solución para ello. Intenté usar este enfoque, pero tuve que parar de inmediato. Cuando intenté asignar un espacio de nombres a mis clases relacionadas con la vista (digamos un CustomTableViewCell), el autocompletado en el generador de interfaces no lo sugirió. Tendría que copiar y pegar manualmente el nombre de la clase para la vista si hubiera utilizado este enfoque.
ArG
1
Por lo general, usaría un enum, no un struct, por lo que no puede crear una instancia de a Foo.
Kevin
7
Swift usa módulos como Python (ver aquí y aquí ) y como @Kevin Sylvestre sugirió, también puede usar los tipos anidados como espacios de nombres.
Y para extender la respuesta de @Daniel A. White, en WWDC estaban hablando de los módulos rápidamente.
Los tipos inferidos hacen que el código sea más limpio y menos propenso a errores, mientras que los módulos eliminan los encabezados y proporcionan espacios de nombres.
Estoy buscando paquetes como construcción como se menciona en su segundo enlace 6.4 Paquetes (Python), los espacios de nombres como tipos anidados no pueden llegar muy lejos, ¿qué pasa si tengo 10 clases diferentes y en diferentes archivos en un espacio de nombres o digamos un ¿¿¿paquete???
user2727195
7
Los espacios de nombres son útiles cuando necesita definir una clase con el mismo nombre que la clase en el marco existente.
Supongamos que su aplicación tiene MyAppnombre y necesita declarar su costumbre UICollectionViewController.
¿Por qué? . Porque lo que has declarado se declara en el módulo actual , que es tu objetivo actual . Y UICollectionViewControllerdesde UIKitse declara en UIKitmódulo.
¿Cómo usarlo dentro del módulo actual?
var customController =UICollectionViewController()//your custom class
var uikitController =UIKit.UICollectionViewController()//class from UIKit
¿Cómo distinguirlos de otro módulo?
var customController =MyApp.UICollectionViewController()//your custom class
var uikitController =UIKit.UICollectionViewController()//class from UIKit
Puede extensionusar el structenfoque de s mencionado para el espacio de nombres sin tener que sangrar todo su código hacia la derecha. He estado jugando con esto un poco y no estoy seguro que me gustaría ir tan lejos como la creación Controllersy Viewsespacios de nombres, como en el siguiente ejemplo, pero ilustra hasta qué punto puede ir:
Profiles.swift :
// Define the namespaces
structProfiles{structViews{}structViewControllers{}}
Perfiles / ViewControllers / Edit.swift
// Define your new class within its namespace
extensionProfiles.ViewControllers{classEdit:UIViewController{}}// Extend your new class to avoid the extra whitespace on the left
extensionProfiles.ViewControllers.Edit{overridefunc viewDidLoad(){// Do some stuff
}}
Perfiles / Vistas / Editar.swift
extensionProfiles.Views{classEdit:UIView{}}extensionProfiles.Views.Edit{overridefunc drawRect(rect:CGRect){// Do some stuff
}}
No he usado esto en una aplicación ya que aún no he necesitado este nivel de separación, pero creo que es una idea interesante. Esto elimina la necesidad de sufijos de clase pares, como el sufijo ubicuo * ViewController, que es molestamente largo.
Sin embargo, no acorta nada cuando se hace referencia, como en parámetros de métodos como este:
Respuestas:
Respondido por SevenTenEleven en el foro de desarrollo de Apple :
También Chris Lattner tuiteó sobre el espacio de nombres .
Parece ser muy diferente lo que he estado pensando.
fuente
forums.developer.apple.com
sitio de foros, desafortunadamente.Describiría el espacio de nombres de Swift como aspiracional; Se le ha dado mucha publicidad que no corresponde a ninguna realidad significativa sobre el terreno.
Por ejemplo, los videos de WWDC establecen que si un marco que está importando tiene una clase MyClass y su código tiene una clase MyClass, esos nombres no entran en conflicto porque el "cambio de nombre" les da diferentes nombres internos. En realidad, sin embargo, sí entran en conflicto, en el sentido de que MyClass de su propio código gana, y no puede especificar "No, no, me refiero a MyClass en el marco": decir
TheFramework.MyClass
que no funciona (el compilador sabe a qué se refiere , pero dice que no puede encontrar esa clase en el marco).Mi experiencia es que Swift, por lo tanto, no tiene espacio de nombres en lo más mínimo. Al convertir una de mis aplicaciones de Objective-C a Swift, creé un marco incrustado porque era muy fácil y genial de hacer. Sin embargo, al importar el marco, se importan todas las cosas de Swift en el marco, por lo que, una vez más, solo hay un espacio de nombres y es global. Y no hay encabezados Swift, por lo que no puede ocultar ningún nombre.
EDITAR: en la semilla 3, esta característica ahora está comenzando a estar en línea, en el siguiente sentido: si su código principal contiene MyClass y su marco MyFramework contiene MyClass, el primero eclipsa al segundo de forma predeterminada, pero puede alcanzar el que está en el marco mediante el uso de la sintaxis
MyFramework.MyClass
. ¡Así, de hecho, tenemos los rudimentos de un espacio de nombres distinto!EDITAR 2: ¡ en la semilla 4, ahora tenemos controles de acceso! Además, en una de mis aplicaciones tengo un marco incrustado y, por supuesto, todo estaba oculto de forma predeterminada y tuve que exponer todos los bits de la API pública explícitamente. Esta es una gran mejora.
fuente
Foundation.NSArray
.Mientras experimentaba un poco con esto, terminé creando estas clases de "espacios de nombres" en sus propios archivos extendiendo el "paquete" raíz. No estoy seguro de si esto va en contra de las mejores prácticas o si tiene alguna implicación que yo sepa (?)
AppDelegate.swift
PackageOne.swift
PackageTwo.swift
PackageOneClass.swift
PackageTwoClass.swift
Editar:
Me acabo de enterar de que crear "subpaquetes" en el código anterior no funcionará si se usan archivos separados. ¿Quizás alguien pueda insinuar por qué ese sería el caso?
Agregar los siguientes archivos a lo anterior:
PackageOneSubPackage.swift
PackageOneSubPackageClass.swift
Está arrojando un error de compilación: 'SubPackage' no es un tipo de miembro de 'PackageOne'
Si muevo el código de PackageOneSubPackageClass.swift a PackageOneSubPackage.swift, funciona. ¿Nadie?
Edición 2:
Jugueteando con esto todavía y descubrí (en Xcode 6.1 beta 2) que al definir los paquetes en un archivo se pueden extender en archivos separados:
Aquí están mis archivos en un resumen: https://gist.github.com/mikajauhonen/d4b3e517122ad6a132b8
fuente
Creo que esto se logra usando:
Entonces se puede acceder usando:
fuente
enum
, no unstruct
, por lo que no puede crear una instancia de aFoo
.Swift usa módulos como Python (ver aquí y aquí ) y como @Kevin Sylvestre sugirió, también puede usar los tipos anidados como espacios de nombres.
Y para extender la respuesta de @Daniel A. White, en WWDC estaban hablando de los módulos rápidamente.
También aquí se explica:
fuente
No necesita prefijos y subclases como este:
Hazlo asi:
¿Por qué? . Porque lo que has declarado se declara en el módulo actual , que es tu objetivo actual . Y
UICollectionViewController
desdeUIKit
se declara enUIKit
módulo.¿Cómo usarlo dentro del módulo actual?
¿Cómo distinguirlos de otro módulo?
fuente
Puede
extension
usar elstruct
enfoque de s mencionado para el espacio de nombres sin tener que sangrar todo su código hacia la derecha. He estado jugando con esto un poco y no estoy seguro que me gustaría ir tan lejos como la creaciónControllers
yViews
espacios de nombres, como en el siguiente ejemplo, pero ilustra hasta qué punto puede ir:Profiles.swift :
Perfiles / ViewControllers / Edit.swift
Perfiles / Vistas / Editar.swift
No he usado esto en una aplicación ya que aún no he necesitado este nivel de separación, pero creo que es una idea interesante. Esto elimina la necesidad de sufijos de clase pares, como el sufijo ubicuo * ViewController, que es molestamente largo.
Sin embargo, no acorta nada cuando se hace referencia, como en parámetros de métodos como este:
fuente
En caso de que alguien tuviera curiosidad, a partir del 10 de junio de 2014, este es un error conocido en Swift:
De SevenTenEleven
"¡ Error conocido, lo siento! Rdar: // problem / 17127940 Los tipos de Swift que califican por su nombre de módulo no funcionan".
fuente