Enumeraciones

Las enumeraciones en Swift comprenden una de sus características más poderosas. El propósito de una enumeración es agrupar semánticamente un grupo de opciones.

Se declaran usando la palabra reservada enum:

enum UserType {
    case admin
    case editor
    case author
    case reader
}

El listado de código anterior define una enumeración llamada UserType que tiene como opciones .admin, .editor, .author y .reader. En este contexto, nuestro programa ahora cuenta con un nuevo tipo de dato UserType y podemos usarlo al igual que usaríamos cualquier Int ó String.

// Una estructura User que tiene una propiedad type de tipo UserType
struct User {
	let type: UserType = .admin
}


func userDidLogin(user: User) {
	switch user.type {
		case .admin:
			// Mostrar el panel de administrador
			
		case .editor:
			// Mostrar el panel de edición
			
		case .author:
			// Mostrar el panel de autores
			
		case .reader:
			// Mostrar lista de lectura
	}
}

En el ejemplo anterior, hay una estructura User con una propiedad type: UserType, la cual sirve como referencia para determinar si el usuario en cuestión puede o no acceder al panel de administrador.

Este tipo de aplicaciones es muy común cuando se trata de enumeraciones en Swift: una lista de posibles valores, a partir de los cuales se van a tomar decisiones.

Con datos de respaldo

Cuando UserType fue declarado anteriormente, no se le asignó ningún tipo de dato a cada uno de los miembros de la enumeración.

Las enumeraciones también se pueden crear a partir de datos brutos, o raw values. Los miembros de una enumeración que tiene datos de respaldo pueden ser creados a partir de dichos datos.

Ejemplo:

enum PodiumPlace: Int {
	case first = 1
	case second = 2
	case third = 3
}


let firstPlace: PodiumPlace = .first		// #=> firstPlace.rawValue == 1
let secondPlace = PodiumPlace(rawValue: 2)	// #=> secondPlace.rawValue == 2

Usando el constructor rawValue: podemos pasar un argumento del tipo de dato que respalda a la enumeración. Si el dato que pasamos al constructor es igual a uno de los declarados en la enumeración, se generará una instancia de la enumeración.

Algunos puntos a considerar sobre las enumeraciones con datos de respaldo:

  1. Todos los miembros de la misma deben de tener el mismo tipo de dato de respaldo. No se puede declarar una enumeración enum Foo: Int y asignarle cadenas de texto a sus miembros.
  2. El constructor rawValue retornará nil si el valor proporcionado no corresponde a ningún miembro de la enumeración.

Valores de respaldo implícitamente declarados

Cuando se quiere trabajar con enumeraciones con datos de respaldo que siguen una secuencia lógica, como el ejemplo anterior (1, 2, 3), se puede declarar solamente el valor que inicia la secuencia, y Swift inferirá el resto de los valores:

enum PodiumPlace: Int {
	case first = 1
	case second
	case third
}

print(PodiumPlace.third.rawValue) // #=> 3

De la misma forma, cuando se requiere que el tipo de dato de respaldo sea String, siempre y cuando los valores brutos de cada miembro sean iguales a los miembros de la enumeración, se puede omitir la declaración explícita:

enum UserType: String{
	case admin
	case reader
}

print(UserType.admin.rawValue) // #=> "admin"

let reader = UserType(rawValue: "reader")
let superAdmin = UserType(rawValue: "super_admin")

print(reader.rawValue) 	// #=> "reader"
print(superAdmin)		// #=> nil

enums con tipos de datos asociados

Las enumeraciones, además poder tener tipos de dato de respalo, pueden, por así decirlo, transportar datos.

enum Result {
    case error(Int, String)
    case success(AnyObject)
}

En el listado de código anterior definimos una enumeración con dos cases que pueden transportar datos: .error que tiene asociados un Int y un String, y .success, que puede transportar cualquier objeto.

let error = Result.error(404, "Not Found")

switch error {
case .error(let code, let description):
	// Mostrar el error al usuario, y/ó realizar operaciones necesarias

case .success(let value):
	// La operación no tuvo errores, value contiene el resultado esperado
}

El listado anterior muestra cómo podemos trabajar cuando tenemos enumeraciones con datos asociados.


Relacionados