Este documento explica las enumeraciones en Swift. Las enumeraciones permiten definir un conjunto de valores relacionados y usarlos para tipificar variables y propiedades. Pueden tener valores asociados y manejarse con switch. Por ejemplo, se define un enum de tipo de golpe con valores de daño para usar en un juego y calcular el daño a enemigos. Las enumeraciones son útiles para controlar tipos de valores acotados.
3.3 Tipos de conexiones en los transformadores trifasicos.pdf
Swift Enumeraciones y Golpes
1. 26/4/2015 Curso de Swift Lección 6, Enumeraciones | Apple Coding
http://applecoding.com/cursos/curso-swift-leccion-6-enumeraciones 1/6
Swift Lección 6, Enumeraciones
Julio César Fernández Cursos 517 Lecturas
Enumerar, exponer o nombrar de manera sucesiva y uno tras otro los elementos que forman un conjunto,
una serie o un todo. Esa es la definición del diccionario y nos da un idea clara de qué son las
enumeraciones. Son un conjunto de datos de un mismo tipo que agrupa valores que se relacionan
entre sí. Normalmente se usan para acotar posibles características de una propiedad, donde uno de los
valores de la enumeración es asignado a una variable tipificada en esta.
Por ejemplo, si tenemos una propiedad de la clase vehículo que es ruedas, es fácil saber qué valores
vamos a poner: 1, 2, 3 o 4. Podemos usar un entero y poner los valores. Pero, ¿y sí queremos que estos
sean los únicos posibles valores de nuestro campo? Usamos las enumeraciones.
enum ruedas {
case una, dos, tres, cuatro
}
Las enumeraciones tienen dos tipos de valores: la descripción y el valor interno o valor hash. Nosotros
siempre trabajaremos con la descripción, pero internamente el sistema les asigna un valor y es
como reconoce cada correspondencia. Si definimos un enum como en el ejemplo, tal cual y sin tipo, los
valores siempre se asociarán de manera automática y solo dispondremos de cada valor como propiedad
del tipo, aunque podremos acceder a su hashValue.
Si escribimos ruedas. veremos que inmediatamente se despliega un selector para elegir cualquiera de
Otras recomendaciones
Swift Lección 5, Tuplas
Nueva lección del curso de Swift, sobre uno
de los nuevos elementos que incorpora el
lenguaje: las tuplas. Un elemento de gran
utilidad en nuestro código y que en cierto
modo ya hemos usado de manera indirecta
anteriormente, tanto en funciones como
enumeraciones de colecciones de datos.
2. 26/4/2015 Curso de Swift Lección 6, Enumeraciones | Apple Coding
http://applecoding.com/cursos/curso-swift-leccion-6-enumeraciones 2/6
sus posibles valores y vemos un curioso ruedas.Type como tipo. Esto
es debido a que la descripción es la propiedad Type de dicha
enumeración.
ruedas.una
ruedas.una.hashValue
Mientras la primera instrucción nos devolverá un escueto (Enum Value), lógicamente, la llamada a
hashValue nos devolverá 0, que es el índice interno que ha autoasignado nuestra enumeración.
También podemos establecer nosotros qué valor queremos que tenga internamente para poder
usarlo. Por ejemplo, si queremos que además de tener nuestra descripción, su valor interno corresponda
con el número de ruedas real. Para ello usamos otro concepto que es el valor raw o de clasificación. Este
solo puede usarse si tipificamos el enum a un tipo de valor, como un String, un flotante, un entero
o un carácter. Estos son los únicos tipos soportados, pues son tipos que el sistema conoce como
hashables o que pueden tener un índice interno de clasificación.
enum ruedas:Int {
case una = 1, dos = 2, tres = 3, cuatro = 4
}
ruedas.dos.hashValue
ruedas.dos.rawValue
Si cambiamos la definición de ruedas por la nueva con valores fijos, cuando accedemos a hashValue o a
rawValue, vemos que los datos son diferentes. El valor dos, tiene el hashValue 1 (su índice en función del
lugar en que se ha enumerado) pero su rawValue es 2, con lo que si queremos usar el valor numérico
de ruedas en alguna función solo tendremos que acceder al rawValue de la propiedad que tenga el
número de ruedas y se asignará sin problema como entero.
De hecho, como los valores son consecutivos, podemos omitir los valores posteriores al 1 y el sistema
entenderá que los demás valores son una sucesión de números donde ha de sumar uno a cada nuevo
valor.
enum ruedas:Int {
case una = 1, dos, tres, cuatro
}
Si volvemos a buscar el rawValue de ruedas.dos, veremos que sigue siendo el entero 2 aunque no lo
hayamos asignado. Esto resulta muy útil cuando tenemos muchos valores. Tenemos que notar que
cualquier valor que dejemos en blanco, habiendo asignado uno anterior, siempre incrementará el
siguiente. Si pusiéramos que dos fuera igual a 3, tres sería igual a 4 y cuatro a 5.
A nivel de definición podemos separar por comas con una sola instrucción case los diferentes
3. 26/4/2015 Curso de Swift Lección 6, Enumeraciones | Apple Coding
http://applecoding.com/cursos/curso-swift-leccion-6-enumeraciones 3/6
valores o podemos poner uno en cada línea antecedido de case. Es una opción a escoger según
nuestras necesidades estéticas de código o cómo queramos que se entienda.
enum ruedas:Int {
case una = 1
case dos
case tres
case cuatro
}
La forma de usar estas enumeraciones es asignarlas como tipo de dato a una variable.
var numRuedas:ruedas
numRuedas = .una
Como la variable numRuedas ya está tipificada de tipo ruedas, no tenemos que poner ruedas.una, si no
que simplemente ponemos un punto y el valor. Asignando .una el sistema ya sabe al enum que
corresponde y valida en tiempo de edición que la asignación y el valor sea correcto en todos los casos.
Trabajando con los enums
Una de las funciones más comunes para una enumeración es usar un switch que nos permita
diferentes flujos en función de un valor enumerado. La ventaja de poder usar los datos descriptivos y
que sus valores internos sean transparentes añade una gran versatilidad para definir tipos de estado de
una app, tipos de personajes de un juego o diferentes tipos o estados de cualquier tipo de objeto y actuar
en consecuencia.
var numRuedas:ruedas = .dos
switch numRuedas {
case .una: println("Un monociclo")
case .dos: println("Un ciclomotor")
case .tres: println("Un triciclo")
case .cuatro: println("Coche")
}
La instrucción switch en este caso nos permite no incluir una opción default ya que en nuestro caso,
todas las posibles opciones de valor que tiene numRuedas están contempladas, por lo que nos ahorramos
esa parte. La seguridad de Swift nos obliga siempre a tener en cuenta que ningún switch se quede
sin evaluar ninguno de sus casos, y en este caso, los hemos contemplados todos. Es lo que se llama
modo exhaustivo. En caso de no incorporarlos todos, entonces sí deberemos usar el default, obviamente.
Valores asociados
Otra de las prácticas que podemos hacer con las enumeraciones es establecer valores a un tipo concreto y
luego supeditar su correspondencia no solo al tipo concreto de enumeración si no a uno o varios
valores asociados. Cada case contemplará un único caso, pero obteniendo el valor asociado con una
asociación directa, podemos trabajar con el dato que contiene cada caso.
4. 26/4/2015 Curso de Swift Lección 6, Enumeraciones | Apple Coding
http://applecoding.com/cursos/curso-swift-leccion-6-enumeraciones 4/6
Vamos a suponer un juego donde queremos controlar el tipo de daño que queremos infringir a un
enemigo en función de cada arma que usemos. Pero queremos que el daño del arma no sea lineal si
no que podamos tener varios niveles de daño y un número de puntos que haga a los enemigos y que
podrá variar en el transcurso del juego (como un arma de un juego de rol convencional que va cogiendo
más poder y daño en el transcurso del juego).
Para ello creamos un enum que nos permita discernir el tipo de golpe que podemos dar con cada una de
las armas: leve, medio, fuerte o mortal. Pero además, nos interesa que el valor de dicho golpe esté
almacenado en el propio enum, porque habrá casos donde un golpe medio haga un daño y otros
donde infrinja un poco más que otra, siendo también medio.
enum golpe {
case golpeLeve(Int)
case golpeMedio(Int)
case golpeFuerte(Int)
case golpeMortal
}
De esta simple forma, hemos extendido la funcionalidad del enum porque ahora la casuística no estará
limitada solo al tipo, sino también al valor interno que almacenemos y que indique cuántos puntos
quitamos al infligir dicho daño. Salvo en el golpe mortal donde quitamos todos los puntos que se tengan.
Hemos de tener presente que el enum es un valor único de por sí de los posibles dentro de una variable,
por lo que podemos asignar sola una de las opciones a cada variable de tipo golpe.
class arma {
var tipoGolpe:golpe?
}
let espada = arma()
espada.tipoGolpe = .golpeMedio(4)
Tenemos una clase arma donde una de sus propiedades va a ser el tipo de golpe. La definimos como
opcional porque aun no sabemos qué valor vamos a darle. Luego creamos una constante espada donde
instanciamos la clase arma y asignamos a espada el tipo de golpe que dará, en este caso un golpe medio
que infrinja un daño de 4.
Vamos a aplicar un caso práctico de daño a un personaje. Creamos nuestra clase personaje con las
propiedades vida y fuerza a 100 y creamos un guerrero.
class personaje {
var vida = 100
var fuerza = 100
}
let guerrero = personaje()
Ahora vamos a golpearlo con el arma. Vamos a suponer que el daño leve quita a la vida los puntos que
5. 26/4/2015 Curso de Swift Lección 6, Enumeraciones | Apple Coding
http://applecoding.com/cursos/curso-swift-leccion-6-enumeraciones 5/6
tenga asignada el arma, el daño medio quita el doble de los puntos, el fuerte el doble de los puntos pero
también resta dichos puntos a la fuerza y el mortal, obviamente, deja la vida a 0 y mata al personaje.
switch espada.tipoGolpe! {
case .golpeLeve(let puntos):
guerrero.vida -= puntos
case .golpeMedio(let puntos):
guerrero.vida -= puntos*2
case .golpeFuerte(let puntos):
guerrero.vida -= puntos*2
guerrero.fuerza -= puntos
case .golpeMortal:
guerrero.vida = 0
}
Si ahora vemos el valor de vida del personaje, veremos que la vida de este es 92, es decir el doble de los
puntos porque hemos establecido que la espada da un golpe medio de daño 4.
guerrero.vida
¿Qué pasa en un buen juego de rol cuando matamos muchos enemigos con un arma? Que esta sube su
poder y el daño que infringe. Vamos a suponer que queremos aumentar el daño de la espada. Solo
tenemos que cambiar el tipo de golpe que dará y el número de puntos. Vamos a cambiar entonces para
que espada de un golpe fuerte de 8 puntos.
espada.tipoGolpe = .golpeFuerte(8)
Si volvemos a preguntar por los valores del personaje tras el cálculo de su daño, veremos que ahora ha
infringido daño en vida y además en fuerza. De esta simple manera, una misma arma puede infringir
diferentes daños y tipos de daño.
En el switch también podemos supeditar valores de la variable interna usando la sentencia where,
de forma que por ejemplo, para un mismo caso, si el valor interno cumple una condición hará una cosa y
si cumple otra se irá a otro flujo.
switch espada.tipoGolpe! {
case .golpeLeve(let puntos):
guerrero.vida -= puntos
case .golpeMedio(let puntos) where puntos <= 5:
guerrero.vida -= puntos*2
case .golpeMedio(let puntos) where puntos > 5:
guerrero.vida -= puntos*3
case .golpeFuerte(let puntos):
guerrero.vida -= puntos*3
guerrero.fuerza -= puntos
case .golpeMortal:
guerrero.vida = 0
default:()
}
En este caso, el golpe medio tiene dos casos: si estamos dando un golpe medio y el valor de puntos que
lleva el enum es menor o igual a 5, entonces hacemos un daño que sea el doble de los puntos. Pero si es
6. 26/4/2015 Curso de Swift Lección 6, Enumeraciones | Apple Coding
http://applecoding.com/cursos/curso-swift-leccion-6-enumeraciones 6/6
mayor de 5, entonces hacemos que el daño sea el triple. Como vemos, así podemos obtener flujos extra
y conseguir que para un mismo enum podamos tener diferentes casos.
Resumiendo
La enumeración, como hemos visto, permite controlar diferentes tipos de valores acotados y es muy
práctico cuando queremos controlar algún tipo de algo de una forma que sepamos, más semánticamente,
en qué se distinguen los diferentes tipos.
Como siempre, os invitamos a que probéis, inventéis vuestros propios casos y juguéis con ellos. Además,
repasad si es necesario todas las lecciones del curso de Swift. Hasta la próxima lección, y como siempre, Good Apple
Coding.
Compártelo:
Facebook 2 Twitter 4 Google LinkedIn 5 Pocket Correo electrónico