En esta primera entrega del curso de Swift 4 vamos a ver los aspectos básicos fundamentales para conocer el lenguaje.
Gran parte de los puntos revisados aquí serán utilizados en prácticamente cualquier programa que desarrollemos de aquí en más.
Tabla de contenidos
Aspectos básicos 1 – Constantes y variables
Al momento de desarrollar un programa es necesario poder guardar información temporalmente en la memoria del dispositivo.
Las constantes y variables pueden verse como casilleros de la memoria en donde el desarrollador decide guardar un dato en ellos para poder ser accedidos más adelante mientras dure la ejecución del programa.
En este sentido, se define una variable como un espacio en memoria que puede ser modificado por un algoritmo y una constante como su contrapartida de solo lectura, el cual no puede ser modificado una vez obtenido un valor inicial.
Para poder utilizarlos, se define un nombre descriptivo de su contenido y se les asocia un tipo de dato.
Para definir una variable se usa la palabra reservada var
mientras que para una constante, la palabra let
:
[code lang=»Swift»]
let cantidadMaximaDeJugadoresPorEquipo = 11
var cantidadDeDelanteros = 2
[/code]
En el ejemplo anterior, se declara una constante con la cantidad máxima de jugadores por equipo en un partido de futbol.
Dado que esa cantidad siempre vale lo mismo es conveniente declararlo como una constante. Por otro lado, se declara una variable con la cantidad de delanteros que puede tener un equipo y en este caso se lo igualó a 2.
Cabe destacar que este valor puede ir modificándose a medida que transcurre el tiempo, por lo tanto es correcto utilizar una variable para guardar este dato.
Si bien la declaración anterior es perfectamente válida se nos esta perdiendo algo. Dijimos que una variable o constante asocia un nombre a un tipo de dato y a un valor y sin embargo, en ningún momento especificamos el tipo de dato que esa variable o contante está teniendo.
Esto se da porque Swift utiliza lo que se llama inferencia de tipos, o sea que “adivina” el tipo de dato que se quiere guardar utilizando como referencia el valor que le estamos asignando.
Yendo a los ejemplos anteriores, en ambos casos asignamos valores numéricos enteros, por lo tanto Swift infiere que ambos son del tipo Int
.
De todas formas, en el caso en el que se quiera indicar el tipo de dato de manera explícita se puede escribir al mismo luego del nombre de la variable separados por dos puntos (:) como se puede apreciar a continuación:
[code lang=»Swift»]
var nombreDeUsuario: String = «Gabriel»
let cantidadDeMesesEnUnAño: Int = 12
[/code]
Como se puede ver en los ejemplos, se está escribiendo el nombre de la variable o constante, seguida de dos puntos, el tipo de dato y por ultimo el valor que se le asigna.
Aspectos básicos 2 – Imprimiendo valores
En el caso en que se quiera imprimir en la consola de Xcode el valor de una constante o variable, Swift provee la función print(_:separator:terminator:)
:
[code lang=»Swift»]
print(nombreDeUsuario)
//Devuelve:
//Gabriel
[/code]
La función print
es una función global que imprime uno o más valores. Posee dos parámetros que tienen valores por defecto, los cuales son separator y terminator. Esto implica que al momento de invocar a la función print
, estos parámetros pueden ser omitidos por completo.
En caso de no especificar nada, esta función agrega al final de la línea un retorno de carro o salto de línea (un enter). Si se quiere indicar que al final de la función el cursor se mantenga en la misma línea, se debe pasar un string vacío al parámetro terminator
:
[code lang=»Swift»]
print(nombreDeUsuario, terminator:»»)
//Devuelve:
//Gabriel
[/code]
Más adelante en el capitulo de funciones Swift vamos a ver en detalle como funcionan los parámetros y los tipos de funciones que existen.
Una técnica muy utilizada a la hora de imprimir valores usando print
, es la de interpolación de cadenas. Gracias a ella se puede especificar un espacio dentro de la cadena de texto para que sea reemplazado por el valor de una variable o constante al momento de ejecutarse. Se utiliza una barra invertida y se encierra la variable o constante entre paréntesis:
[code lang=»Swift»]
print(«De los \(cantidadMaximaDeJugadoresPorEquipo), \(cantidadDeDelanteros) están jugando como delanteros»)
//Devuelve:
//De los 11, 2 están jugando como delanteros
[/code]
A diferencia de otros lenguajes, Swift no requiere el uso del punto y coma al finalizar una sentencia. Sin embargo, está permitido su uso en caso de quererlo hacer:
[code lang=»Swift»]
print(nombreDeUsuario);
//Devuelve:
//Gabriel
[/code]
Aspectos básicos 3 – Comentarios
Es muy común escribir texto dentro del código que no queremos que sea ejecutado pero que nos sirve como anotaciones o recordatorios. Estos comentarios son ignorados por el compilador y no son ejecutados.
Existen dos tipos de comentarios. Por un lado, tenemos a los de línea, quienes comienzan con dos barras o diagonales:
[code lang=»Swift»]
//Esto es un comentario de linea
[/code]
Por otro lado, tenemos los comentarios multilineas, que se encierran entre /* y */ :
[code lang=»Swift»]
/* Esto es un comentario
de
varias
líneas */
[/code]
Aspectos básicos 4 – Operadores básicos
Los operadores básicos incluidos en Swift son los siguientes:
- Adición (+)
- Sustracción (-)
- Multiplicación (*)
- División (/)
- Resto (%) –> hace referencia al resto de una división. Ej: 10/3 es igual a 3 y sobra 1. Por lo tanto, el resto es 1.
- Asignación (=) -> Se usa para darle un valor a una variable o constante, como vimos en los ejemplos.
- Igual a (==)
- Distinto a (!=)
- Mayor a (>)
- Menor a (<)
- Mayor o igual (>=)
- Menor o igual (<=)
Aspectos básicos 5 – Tipos de dato
En Swift podemos encontrar los siguientes tipos de dato:
- Números enteros: Int y UInt
- Números de coma flotante: Float y Double
- String y Character
- Bool
- Tuplas
- Tipos de Colección: Array, Set y Dictionary
En este post vamos a ver los usos más comunes de cada uno. Cabe mencionar que los tipos de dato se escriben con Mayúsculas la primer letra.
Números enteros
Los números enteros son aquellos que no poseen parte decimal o fracción, como el 1, 2, 3, 58 y -90. Existen dos tipos:
- Con signo (signed): Son aquellos que pueden ser negativos, cero o positivos. Existen en sus versiones de 8, 16, 32 y 64 bits llamados de la siguiente manera:
- Int8
- Int16
- Int32
- Int64
Asimismo, Swift provee una versión adicional llamada Int
que coincide en tamaño con aquel que posee la misma cantidad de bits que el sistema en donde se está ejecutando. Esto es, si el sistema es de 32 bits, entonces Int
tiene el mismo tamaño que Int32
y, si el sistema es de 64, equivale al Int64
.
- Sin signo (unsigned): Son aquellos que pueden ser cero o positivos. De la misma manera que los anteriores, Swift provee el tipo
UInt
que coincide conUInt32
oUInt64
, dependiendo de la cantidad de bits del sistema. Las otras versiones de 8 y 16 bits también están disponibles.
Si bien ambos tipos están disponibles, es recomendable siempre usar Int
.
[code lang=»Swift»]
let numero1 = 5
print(numero1)
//Devuelve:
//5
let numero2 = numero1 + 6
print(numero2)
//Devuelve:
//11
var numero3:Int32 = 90
numero3 = numero3 + 40
print(numero3)
//Devuelve:
//130
[/code]
Números de coma flotante
Son aquellos números que poseen parte decimal, como por ejemplo: 3.14 o -45.392607. Existen dos tipos:
- Double: se utiliza para representar un número de coma flotante de 64 bits
- Float: se utiliza para representar un número de coma flotante de 32 bits
El hecho de que Double
sea de 64 bits implica que puede almacenar un mayor rango de valores, con una precisión de al menos 15 decimales, lo que lo hace preferible en cuanto a su uso en casos generales.
String y Character
Un Character
es un carácter cualquiera mientras que un String
es una cadena de texto o bien, una colección de Characters.
Para poder usar un String
, basta con crear una constante o variable y asignarle la cadena de texto que queramos que almacene, encerrado entre comillas dobles:
[code lang=»Swift»]
let texto1 = «Esto es un String»
[/code]
En algunas implementaciones, es posible necesitar crear un String
vacío inicialmente para luego asignarle un valor más adelante. Para lograr ese comportamiento, se puede utilizar una cadena vacía o usar el inicializador que trae String
:
[code lang=»Swift»]
var textoVacio = «»
var textoVacio2 = String()
textoVacio = «Hola Mundo!»
textoVacio2 = «Hola Mundo!»
[/code]
Asimismo, se puede modificar una cadena de texto utilizando el operador +=, siempre que la misma esté declarada como una variable:
[code lang=»Swift»]
textoVacio += » cómo están?»
print(textoVacio)
//Devuelve:
//Hola Mundo! cómo están?
[/code]
Como dijimos anteriormente, un String
puede verse también como un conjunto de Characters. Por lo tanto, si queremos concatenar un Character
a un String
la operatoria es un poco distinta. Si usamos la técnica anterior la misma no va a funcionar ya que un String
solo puede concatenarse con otro String
. Sin embargo, podemos hacer uso del método append
de String
para agregar el Character en cuestión. Un punto a tener en cuenta es que para usar una variable de este tipo, es necesario especificar el tipo de dato, ya que de lo contrario Swift inferirá que se trata de un String
:
[code lang=»Swift»]
let exclamacion:Character = «!»
textoVacio.append(exclamacion)
print(textoVacio)
//Devuelve:
//Hola Mundo! cómo están?!
[/code]
En el ejemplo, se declara una constante exclamación del tipo Character
y se le asigna un valor. Como se aclaró previamente, es necesario indicarle al compilador que esta constante es del tipo Character
, de lo contrario inferirá que se trata de un String
de un solo carácter.
Por último, Swift incorpora una técnica muy utilizada llamada Interpolación de Cadenas (String interpolation) que permite armar una cadena de texto combinando texto, números, funciones, variables y otras expresiones. Cada ítem a incluir en la cadena debe ser encerrada entre paréntesis y precedida por una barra invertida:
[code lang=»Swift»]
let cadena = «El número \(numero3) es más grande que el número \(numero2)»
print(cadena)
//Devuelve:
//El número 130 es más grande que el número 11
[/code]
Como se puede ver en el ejemplo, estamos usando las variables numero2 y numero3 creados anteriormente para armar un texto que los incorpora en un mismo String
resultante. Recordemos que estas variables son del tipo Int
, pero al estar dentro de los paréntesis y la barra, se convierte su tipo o salida a String
y se concatena al resto de la cadena.
Por lo tanto, para concatenar string en Swift tenemos la opción de usar el operador +=, en el cual a una variable String
se le puede adicionar otro a continuación, el operador +, para construir una cadena a partir de otras que se concatenan mediante ese operador, o la interpolación de cadenas, que a su vez nos permite convertir a String
valores de otro tipo de dato e insertarlo dentro de una cadena resultante.
Bool
El tipo de dato booleano permite que una constante o variable pueda valer true
o false
. Son utilizados para tomar decisiones en base a comparaciones lógicas.
[code lang=»Swift»]
let heladeraLlena = false
if heladeraLlena {
print(«A preparar algo para comer!»)
} else {
print(«Tenemos que comprar comida»)
}
//Devuelve:
//Tenemos que comprar comida
[/code]
En el ejemplo anterior, se declara una constante indicando que la heladera no se encuentra llena. Luego se pregunta si la misma está llena, pero al no estarlo se ejecuta solo la sentencia encerrada en el else
.
Tuplas
Las tuplas permiten agrupar varios valores de cualquier tipo en uno solo.
[code lang=»Swift»]
let ubicacion = (-34.599722, -58.381944)
print(«Buenos Aires se encuentra en la longitud \(ubicacion.0)»)
//Devuelve:
//Buenos Aires se encuentra en la longitud -34.599722
[/code]
En el ejemplo anterior, declaramos una tupla del tipo (Double, Double)
con las coordenadas de longitud y latitud de la provincia de Buenos Aires. Luego, usamos la longitud haciendo referencia a ella por su posición en la Tupla (el cual empieza por el índice 0) y se imprime su valor dentro de un String
más grande usando la técnica de String Interpolation.
Un punto a tener en cuenta es que las tuplas pueden contener cualquier cantidad de elementos y los mismos pueden ser a su vez de distintos tipos, como por ejemplo:
- (Int, Int)
- (Int, String)
- (Bool, String, Int)
- (Double, Float, Bool, String, Int)
Otra forma de acceder a los valores que contiene la tupla es mediante el nomenclado de sus elementos. De esta manera, al ponerle un nombre a cada uno, simplemente hacemos referencia a ellos por este atributo:
[code lang=»Swift»]
let registro = (nombre: «Gabriel», esMayorDeEdad: true)
if registro.esMayorDeEdad {
print(«\(registro.nombre) está autorizado a ingresar al club»)
}
//Devuelve:
//Gabriel está autorizado a ingresar al club
[/code]
En este caso, para poder hacer uso de los datos de la tupla registro, simplemente hacemos referencia a los nombres de sus elementos.
Las tuplas son especialmente útiles cuando se utilizan como valores de retorno en funciones, ya que les da la posibilidad de devolver más de un valor al mismo tiempo.
Tipos de colección
Existen tres tipos de colecciones en Swift: los arreglos (o arrays) son colecciones ordenadas de elementos, los Sets son colecciones sin ordenar y con valores únicos y por ultimo, los Diccionarios son listas sin ordenar de elementos clave-valor.
Todos los tipos de colección son claros en cuanto al tipo de dato que almacenan. Esto significa que una vez declaradas las colecciones, solo se podrán agregar elementos del mismo tipo de dato de los que fueron indicados al principio. Por lo tanto, si se dispone de un arreglo de Strings, solo se podrá agregarle Strings y no números enteros o booleanos.
Arreglos
Se trata de colecciones ordenadas de elementos, los cuales pueden aparecer más de una vez dentro del arreglo. Como es una lista ordenada, cada elemento ocupa una posición indicado por un índice que comienza con 0. Por lo tanto, el primer elemento ocupa la posición 0, el segundo la posición 1, etcétera.
Para crear un array, se puede inferir su tipo de acuerdo a los datos iniciales que se le asigna (encerrados entre corchetes) o bien, se puede crear un array vacío usando un inicializador al cual se le debe indicar el tipo de dato:
[code lang=»Swift»]
let arreglo1 = [«uno», «dos» ,»tres»]
print(«El primer elemento del arreglo es \(arreglo1.first!)»)
//Devuelve:
//El primer elemento del arreglo es uno
var arreglo2 = [Int]()
arreglo2.append(1)
arreglo2.append(4)
arreglo2.append(9)
print(«El segundo elemento del arreglo2 es \(arreglo2[1])»)
//Devuelve:
//El segundo elemento del arreglo2 es 4
[/code]
En el primer ejemplo, se infiere que el arreglo será un array de Strings. En cambio en el segundo se crea inicialmente un array de enteros vacío y luego se le agregan 3 datos. Un punto a tener en cuenta es que si queremos ver el primer elemento podemos usar el subíndice 0 o el método first
(al cual le agregamos un signo de exclamación por tratarse de un opcional, lo que veremos más tarde). Si queremos ver el segundo elemento, debemos usar el subíndice 1, como se ve en el segundo ejemplo.
Para eliminar un elemento del array, se utiliza el método remove(at:)
y se indica el subíndice:
[code lang=»Swift»]
arreglo2.remove(at: 1)
print(«El segundo elemento del arreglo2 es \(arreglo2[1])»)
//Devuelve:
//El segundo elemento del arreglo2 es 9
[/code]
Al eliminar el segundo elemento del array, luego su lugar es ocupado por el numero 9 que anteriormente ocupaba el tercer lugar.
Set
Se trata de un tipo de colección de elementos que no siguen un orden y que solo aparecen una vez dentro de la colección. Es útil cuando justamente el orden no es importante o bien, cuando se requiere asegurar que el listado contenga valores únicos.
De la misma manera que los arreglos, podemos crear Sets asignándole valores al momento de declararlo por primera vez o bien, usar un inicializador para crear uno vacío:
[code lang=»Swift»]
let coleccion = Set<Int>()
print(«Tenemos \(coleccion.count) elementos»)
//Devuelve:
// Tenemos 0 elementos
var nombres:Set<String> = [«Lionel»,»Messi»]
[/code]
Un punto a tener en cuenta es que si se quiere usar un Set
inicializándolo pasándole los datos que va a contener (segundo ejemplo) es necesario indicar el tipo de dato del mismo ya que Swift no puede inferir si se trata de un Set o de un Array. En el ejemplo, se indicó el tipo de dato Set
.
Para insertar un valor en la colección se utiliza el método insert(_:)
y para eliminar remove(_:)
:
[code lang=»Swift»]
nombres.insert(«Neymar»)
nombres.insert(«Iniesta»)
for dato in nombres {
print(«\(dato)»)
}
//Devuelve:
//Lionel
//Messi
//Neymar
//Iniesta
nombres.remove(«Neymar»)
for dato in nombres {
print(«\(dato)»)
}
//Devuelve:
//Lionel
//Messi
//Iniesta
[/code]
En el ejemplo anterior, usamos el Set
nombres creado previamente y le agregamos dos valores adicionales. Para mostrar el contenido de la colección, usamos un for
para recorrerlo, en donde se crea una constante temporal llamada dato que contiene el valor de cada elemento según la iteración de la que se trate. Es decir, el for
se ejecuta 4 veces y la primera vez que ingresa, la constante dato es igual a “Lionel”. La segunda equivale a “Messi”, y así. Finalmente eliminamos un elemento y volvemos a recorrer la colección para validar.
Diccionario
Un diccionario permite almacenar asociaciones de pares clave – valor, en donde todas las claves de la colección son del mismo tipo y todos los valores son del mismo tipo pero puede ser distinto que el tipo de la clave. Los elementos aquí guardados no siguen un orden determinado y no pueden repetirse dos elementos con la misma clave.
Se denomina diccionario porque al igual que un diccionario convencional, los valores aquí almacenados son buscados mediante su clave. Es por esto que las claves no pueden repetirse ya que solo se admite devolver un valor al momento de realizar una búsqueda, siempre que la clave exista.
Para poder usar un Diccionario, se debe determinar entre corchetes el par clave – valor, los cuales se separan por dos puntos (:). En el caso de querer indicar el tipo de dato de cada uno de ellos, puede hacerse usando la misma convención.
[code lang=»Swift»]
var monedas: [String:String] = [«ARS»:»Peso argentino», «USD»: «Dolar americano», «MXN»:»Peso Mexicano»]
[/code]
En este caso, se indicó el tipo de dato [String:String]
de manera explícita pero, al asignarle los valores al momento de declarar la variable monedas, es perfectamente válido omitir el tipo de dato ya que el mismo se puede inferir. Es decir, también pudo haberse escrito así:
[code lang=»Swift»]
var monedas = [«ARS»:»Peso argentino», «USD»: «Dolar americano», «MXN»:»Peso Mexicano»]
[/code]
Para poder acceder al valor de una determinada clave basta con indicar la misma como si se tratase de un subíndice:
[code lang=»Swift»]
let peso = monedas[«ARS»]
print(«\(peso!)»)
//Devuelve:
//Peso argentino
[/code]
Si se quiere agregar un nuevo valor, se debe usar la misma técnica vista en el ejemplo anterior pero asignándole un valor:
[code lang=»Swift»]
monedas[«CRC»] = «Colones»
var colones = monedas[«CRC»]
print(«\(colones!)»)
//Devuelve:
//Colones
[/code]
Para modificar un valor cuya clave ya existe, se utiliza la misma técnica:
[code lang=»Swift»]
monedas[«CRC»] = «Colones Costa Rica»
colones = monedas[«CRC»]
print(«\(colones!)»)
//Devuelve:
//Colones Costa Rica
[/code]
Descarga el archivo playground.
Siguiente capítulo: Control de flujo.