En este post y el siguiente vamos a dar un repaso general a los conceptos fundamentales de Swift, lanzado por Apple a finales del año 2014 para crear aplicaciones para sistemas operativos de la marca (iOS y OS X, para iPhone, iPad y ordenadores Mac).
Antes que nada debemos decir que Swift es un lenguaje orientado a objetos, aunque toma aspectos prestados de los lenguajes funcionales. En este punto se asemeja mucho a C#, Java e incluso Objective-C.
Recuerda: Aunque Swift es un lenguaje nuevo, con una sintaxis renovada y más moderno que Objective-C, el runtime y las APIs subyacentes son las mismas de siempre (Cocoa touch y las APIs de iOS) y gran parte de lo que sepas de programar con Objective-C te sirve para Swift también.
Constantes
La palabra clave let permite definir constantes. Al igual que la palabra clave var, soporta inferencia de tipos, por lo que ambas líneas del siguiente bloque de código son válidas:
let message = "Hello world" // message es String
let message : String = "Hello world"
Enumeraciones
Las enumeraciones son otro de los añadidos interesantes de Swift frente a Objective-C. Básicamente una enumeración (enum) permite declarar un conjunto de valores bajo un nombre identificativo. Las enumeraciones de Swift pueden tener métodos asociados y conformar protocolos (más sobre esto luego).
Se parecen mucho más a las enumeraciones de Java o a las enum class de C++ 11 que a las enumeraciones clásicas de C++ o de C#.
Clases
Las clases constituyen uno de los pilares fundamentales de Swift. Al igual que Objective-C, Swift posee herencia simple, es decir, una clase puede heredar tan solo de otra clase, no de varias a la vez. Se pueden formar jerarquías de clases todo lo complejas que sea necesario, pero donde cada clase tenga una sola clase base.
Nota: Swift admite el uso de funciones globales, es decir, funciones definidas fuera de cualquier clase, lo que posibilita desarrollar en Swift mediante un planteamiento más procedural. Aunque las funciones globales tienen sus usos lícitos, es preferible usar un planteamiento orientado a objetos.
Referencias
Swift no tiene punteros, usa referencias en su lugar. Eso significa que no debemos explicitar el tipo puntero para tener una variable que contenga un objeto.
Así, si en Objective-C para declarar una variable que contenga un objeto de un tipo MyClass, debemos declarar la variable como MyClass* (el asterisco significa puntero a, por lo que MyClass* se lee como puntero a un objeto MyClass), en Swift basta con declararla de tipo MyClass.
Esto hace que para el desarrollador el trabajo con objetos sea idéntico al trabajo con tipos simples: en Objective-C una variable de tipo int solía ser simplemente int y no int* (aunque esta segunda es válida en según que contextos). Esto añade una complejidad que en Swift desaparece.
Swift define el valor nil como "ausencia de valor". En Swift por defecto las referencias son no nulables, es decir no pueden contener el valor nil. Para que una referencia sea nulable (y por lo tanto contener el valor nil para indicar que no contiene ningún objeto) debe declararse explícitamente como tal añadiendo ? al final del tipo:
var foo : MyClass = MyClass() // Correcto. Referencia NO nulable asignada a un objeto
var foo : MyClass? = nil // Correcto. Referencia nulable asignada a nil
var foo : MyClass = nil // Incorrecto: Referencia NO nulable asignada a nil
Para acceder al valor de una propiedad de una referencia debe usarse el operador . (punto) o bien el ?. (interrogante-punto) si la referencia es nulable.
Si la clase MyClass tiene una propiedad name, para acceder a ella usaríamos:
var x = f.name // Si f es una referencia NO nulable(MyClass)
var x = f?.name // Si f es una referencia nulable (MyClasss?)
El operador ?. es seguro porque si f vale nil, entonces f?.name no generará ningún error, sino que devolverá nil.
Para convertir una referencia nulable en una no nulable (y por lo tanto "extraer" el objeto que contenga dicha referencia no nulable) se usa el operador ! (admiración):
var x = f! // Si f vale nil dará un error de ejecución. En caso contrario x apuntará al mismo objeto que f, pero x es no nulable
var n = f!.name // Si fa vale nil dará un error de ejecución. En caso contrario n será el valor de la propiedad name del objeto apuntado por f
Nota: Para más información sobre las referencias nulables y no nulables en Swift puedes leer un post anterior publicado en este mismo blog: Swift y los nulos.
La próxima semana veremos unos cuantos conceptos más de Swift y sus diferencias y similitudes con otros lenguajes de programación.