Variables y constantes
Una variable es un contenedor cuyo valor puede variar en el transcurso de la ejecución de nuestro programa. Una constante, por el contrario, es un valor que permanecerá inalterable (o inmutable) durante el mismo. Ambos tipos forman parte de lo que se llaman propiedades.
Las variables se definen con la palabra clave var antecediendo al nombre de la misma y las constantes con la palabra let. Ejemplo:
var saludo = "Hola" var numero = 5 let cantidad = "20 unidades" let pedido = 15
var x = 0, y = 0.0, z = 0, ax = "Prueba", bx = "Otra prueba" let a = 3.0, b = 2, c = 3, aa = "Testeo"
Tipos de datos básicos
Las variables y constantes en Swift pueden ser de muchos tipos y complejidad en cuanto a estructura, pero al final todos tendrán una base en los llamados tipos de datos básicos, que nos permiten guardar los tipos de información más básicos que luego nos permitirán crear otros más complejos.
- Int, número entero de 32 bits con un rango de entre -2.147.483.648 y 2,147,483,647.
- Double, número flotante de 64 bits con hasta 15 decimales de precisión.
- Float, número flotante de 32 bits con hasta 6 decimales de precisión.
- Bool, número booleano que puede ser 0 (false) o 1 (true).
- String, cadena de caracteres, tratada internamente con una matriz (array) de ellos.
Esto serían los tipos básicos que pueden ser usados a la hora de crear variables o constantes. Podemos declararlos indicando los tipos, siempre y cuando queramos tener claro qué contendrán o si queremos evitar que el compilador decida por nosotros.
var mensaje: String = "Hola ¿qué tal?" var pi: Double = 3.14159265 var verdad: Bool = true let veces: Int = 320
Si nos fijamos en los ejemplos que dábamos al comienzo, estos no tenían puesto el tipo de dato que íbamos a usar. Y esto es porque hemos usado la inferencia de datos: la propiedad que tiene el compilador de determinar por nosotros cuál es el tipo de dato a usar en una variable o constante en función de su contenido.
Como unir cadenas?
Podemos unir cadenas de estar forma: var cadena = "hola" var cadena2 = "que" var cadena3 = cadena + " " + cadena2 //Tambien podemos interpolar var numero = 10 var cadena4 = "Numero: \(numero)" print(cadena4)
Array o matrices
Un array o matriz es una colección de elementos almacenados en una sucesión. Por ejemplo, una serie de números, o una serie de cadenas. Tradicionalmente, cuando se define un array de un tipo, este solo puede contener datos de ese tipo (números, cadenas, objetos…), pero en Swift tenemos la posibilidad de crear estos con diferentes tipos de datos.
var mCadenas = ["Uno","Dos","Tres","Cuatro"] var mNumeros = [1,2,3,4] let mCadenaTipificada:[String] = ["Cinco","Seis","Siete"]
Si queremos cambiar un valor de un array, solo hay que hacer una asignación teniendo presente el índice.
mNumeros[3] = 7
A la hora de añadir valores a un array o incluso sustituir y añadir a la vez, tenemos varias opciones interesantes. Para ello, vamos a usar el operador de agregación += que permite añadir elementos a un array o sumar a una variable un valor u otra variable. En realidad, este operador, suma el array que ya tenemos con uno nuevo, motivo por el que aunque sea un solo valor, hemos de ponerlo entre corchetes.
Otras cosas útiles:
//Para conocer el numero de elementos de un array mCadenas.count //Para conocer si el array esta vacio mCadenas.isEmpty
Por último, podemos usar también rangos para acceder o sustituir valores. Por ejemplo, imaginar que queremos cambiar los valores segundo y tercero a la vez (las posiciones 1 y 2). Podemos usar los rangos, un número de inicio y un número de fin separados por 2 puntos y un símbolo menor o 3 puntos. Estos rangos nos permiten indicar que queremos acceder desde el primer valor del rango hasta el anterior al último o hasta el último inclusive. El rango ..< indica desde el valor de inicio hasta el final sin incluir este y … el rango completo. Veámoslo en ejemplos:
var m = ["Mad Men", "Better Call Saul", "Talking Dead", "Humans"] m += ["Preacher"] m += ["The Killing"] // Sustituimos el rango que va del 1 al 2 con dos nuevos valores m[1...2] = ["Prison Break", "Breaking Bad"] // Añadimos dos elementos nuevos m += ["Lost", "Game Of Thrones"] // Y ahora cambiamos esos dos últimos elementos m[4..<8] = ["TWD", "FTWD", m[7], m[6]] print(m)
Es importante notar que cualquier variable queda modificada a la izquierda del = siendo todo lo que hay a la derecha el valor antes de ser modificado. Por eso, las posiciones 7 y 6 son las anteriores a querer cambiar o si hacemos a = a + 1, siendo a igual 2, a la derecha del igual a sigue siendo 2 y a la izquierda, será 3.
Los rangos se usan también para la enumeración de arrays a través de bucles (recorrer todos sus elementos o parte).
En contra de los tipos básicos, los arrays SÍ pueden definirse vacíos. Realmente, no están vacíos pues se inicializan con la estructura, y por eso realmente no están vacíos y podemos crearlos en este estado. La forma de definirlos es usando el doble paréntesis de instancia vacía () y (muy importante) tipificando el dato, por ejemplo, var arrayVacio = [String](). También podemos hacerlo indicando el tipo de dato en formato de primitiva del lenguaje como var arrayVacio = Array<String>()
Diccionarios
Los diccionarios nos permita acceder a sus valores, con los diccionarios nosotros asignamos el valor por el que podremos acceder a los mismos. El contenido de cada posición del diccionario puede ser del tipo que queramos, bien datos básicos, bien datos complejos (como un array u otro diccionario) e incluso datos mucho más complejos como objetos, imágenes o bloques de código.
En Swift, además, podemos usar cualquier tipo de dato básico también para el dato de índice. Pero estos índices, como es lógico, han de ser únicos para cada valor de un diccionario. No pueden usarse índices duplicados.
Tanto en los diccionarios, como en los array, podremos guardar casi cualquier tipo de datos básico, complejo o del tipo que queramos siempre que pueda asignarse a una variable, incluso instanciaciones de una clase (cosa que veremos más adelante, vayamos poco a poco). En cuanto al índice del diccionario, solo pueden usarse tipos básicos, conocidos técnicamente como hashable.
La forma de definir una pareja de clave y dato para un diccionario (que iría en una posición del mismo) es usando el separador : para tipificar índice y valor. Imaginemos que queremos guardar un diccionario con el número de series de AMC. En el caso de TWD estableceríamos su clave y su valor con «TWD»:1. Puestos en una sucesión separados por comas, definimos todos los elementos que necesitemos y podemos asignarlos.
var series = ["TWD": 1, "FTWD": 2]
Como hemos inferido el tipo (no lo hemos indicado), hemos de tener en cuenta que el compilador habrá creado un diccionario con el tipo [String:Int]. Si quisiéramos tipificar el diccionario, forzando los tipos de datos, lo que haremos será usar la estructura que hemos indicado: Dentro de los corchetes, el primer valor es el tipo usado para el índice, seguido de dos puntos y el tipo de dato que vamos a guardar. No hace falta indicar nada más pues [Clave:Valor] será interpretado por el compilador como Dictionary<Key,Value>.
var series:[String:Int] = ["TWD": 1, "FTWD": 2]
La forma de modificar o añadir valores a un diccionario es parecida a los array aunque indicando el valor del índice. Simplemente hacemos referencia a la clave que sustituir o añadir y le asignamos un valor. Si existe, será sustituida y si no existe se añadirá al diccionario. En el caso que queramos enumerar o recorrer todos los valores de un diccionario (que veremos más adelante) los valores aparecerán por orden de inserción, como si fuera un array.
// Cambiamos el valor de TWD por 3 series["TWD"] = 3 // Como Breaking Bad no existía, se añade con un valor de 0 series["Breaking Bad"] = 0
Mutabilidad e inmutabilidad
Para terminar este artículo, vamos a repasar un concepto para que lo podamos tener bien claro: el concepto de la mutabilidad (variable que puede ser modificada) y la inmutabilidad (que no puede ser modificada). Como ya dijimos al comienzo, los tipos de propiedades pueden ser variables o constantes. Si declaramos un diccionario como constante (con let), este será inmutable e intentar modificar un valor del mismo o añadir valores dará errores de compilación. Igual con un array, cuyos valores podremos modificar, borrar elementos o añadirlos a nuestros antojo si es variable (definido con var), pero no podremos hacer nada si es constante.
Como es obvio, si definimos un diccionario como inmutable, hemos de cargar sus valores en el momento de definirlo pues ya no podremos hacerlo después. Como poder, podríamos definirlo vacío si queremos, pero así se quedaría durante todo el programa sin posibilidad de hacer nada más con él.
Aquí es importante que aprendamos un primer concepto sobre variables por valor o por referencia. Las clases, que son un tipo de dato objeto que veremos más adelante, son valores por referencia. De forma que cuando la asignamos a un let lo que tiene este es simplemente la dirección de memoria donde está dicha clase u objeto. Obviamente, ese valor no podrá cambiarse pero el objeto sí es mutable. No hemos de entender que una clase puede modificarse, porque lo que va en el let es solo la dirección donde está: por eso podemos modificarlo.
Del mismo modo, hemos dicho que todas las variables han de estar inicializadas con un valor, pero en el caso de los let podemos definirlos después.
let test:Int test = 3