Guía completa de conceptos fundamentales en Swift

Sintaxis y tipos fundamentales

En Swift, las variables se declaran con var y las constantes con let. Los tipos opcionales se indican con ? y permiten representar la ausencia de un valor.

var mensajeSaludo = "Hola mundo"
let lenguaje = "Swift"

var enteroOpcional: Int? = nil
if let valor = enteroOpcional {
    print("Valor presente: \(valor)")
} else {
    print("Valor nulo")
}

Los alias de tipo con typealias mejoran la legibilidad. Las tuplas agrupan múltiples valores en una sola unidad compuesta.

typealias Coordenadas = (latitud: Double, longitud: Double)
let ubicacion: Coordenadas = (40.4168, -3.7038)

let parNumero = (id: 101, nombre: "Sensor")
print(parNumero.0)  // Acceso por índice
print(parNumero.nombre) // Acceso por nombre

Control de flujo

Las estructuras de control en Swift incluyen bucles for-in y sentencias switch con patrones avanzados.

for i in 0..<5 {
    print("Iteración: \(i)")
}

for _ in 1...3 {
    print("Repetición")
}

let puntuacion = 85
switch puntuacion {
case 0..<60:
    print("Insuficiente")
case 60..<80:
    print("Aprobado")
default:
    print("Sobresaliente")
}

Funciones y closures

Las funciones en Swift pueden tener parámetros predeterminados, variádicos y modificar valores extrenos mediante inout.

func calcularArea(ancho: Double, alto: Double) -> Double {
    return ancho * alto
}

func sumar(valores: Int...) -> Int {
    return valores.reduce(0, +)
}

func intercambiar(_ a: inout Int, _ b: inout Int) {
    (a, b) = (b, a)
}

Los closures son bloques de código autónomos que pueden capturar valores del contexto circundante.

let nombres = ["Carlos", "Ana", "Luis"]
let ordenados = nombres.sorted { (a, b) in
    return a.count < b.count
}

// Simplificación con argumentos abreviados
let longitudes = nombres.map { $0.count }

Estructuras y clases

Las estructuras son tipos de valor, mientras que las clases son tipos de referencia. Las clases soportan herencia y tipos de referencia.

struct Punto {
    var x: Double
    var y: Double
}

class Circulo {
    var centro: Punto
    var radio: Double
    
    init(centro: Punto, radio: Double) {
        self.centro = centro
        self.radio = radio
    }
    
    var area: Double {
        return .pi * radio * radio
    }
}

Enumeraciones y protocolos

Las enumeraciones en Swift pueden tener valores brutos, valores asociados y métodos.

enum ResultadoOperacion {
    case exito(mensaje: String)
    case error(codigo: Int, descripcion: String)
}

let resultado: ResultadoOperacion = .exito(mensaje: "Completado")
if case .exito(let msg) = resultado {
    print(msg)
}

Los protocolos definen interfaces que los tipos pueden adoptar. Se pueden combinar múltiples protocolos.

protocol Describible {
    var descripcion: String { get }
}

protocol Identificable {
    var id: UUID { get }
}

struct Producto: Describible, Identificable {
    let id = UUID()
    var nombre: String
    var precio: Double
    
    var descripcion: String {
        return "\(nombre): $\(precio)"
    }
}

Genéricos y extensiones

Los genéricos permiten crear código flexible y reutilizable para diferentes tipos.

func intercambiarElementos<T>(_ arreglo: inout [T], i: Int, j: Int) {
    let temp = arreglo[i]
    arreglo[i] = arreglo[j]
    arreglo[j] = temp
}

struct Contenedor<Elemento> {
    var elementos: [Elemento] = []
    
    mutating func agregar(_ item: Elemento) {
        elementos.append(item)
    }
}

Las extensiones añaden funcionalidad a tipos existentes sin modificar su código original.

extension Double {
    var metrosAPies: Double {
        return self * 3.28084
    }
    
    func redondear(enteros: Int) -> Double {
        let divisor = pow(10.0, Double(enteros))
        return (self * divisor).rounded() / divisor
    }
}

let longitudMetros = 5.0
print("\(longitudMetros) metros son \(longitudMetros.metrosAPies) pies")

Manejo de errores

Swift utiliza throw, try y catch para el manejo de errores. Los errores se definen como enumeraciones que conforman al protocolo Error.

enum ErrorLectura: Error {
    case archivoNoEncontrado(ruta: String)
    case permisosInsuficientes
}

func leerArchivo(ruta: String) throws -> String {
    guard FileManager.default.fileExists(atPath: ruta) else {
        throw ErrorLectura.archivoNoEncontrado(ruta: ruta)
    }
    // Lógica de lectura aquí
    return "Contenido del archivo"
}

do {
    let contenido = try leerArchivo(ruta: "/ruta/invalida")
    print(contenido)
} catch ErrorLectura.archivoNoEncontrado(let ruta) {
    print("Archivo no encontrado en: \(ruta)")
} catch {
    print("Error desconocido: \(error)")
}

Recursos y aprendizaje

El lenguaje Swift se actualiza constantemente, introduciendo mejoras en sintaxis, rendimiento y nuevas características. Los desarrolladores pueden consultar la documentación oficial y proyectos comunitarios para mantenerse actualizados con las mejores prácticas.

El uso de Playgrounds facilita la experimentación interactiva con el código Swift, permitiendo probar conceptos en tiempo real sin necesidad de configurar proyectos complejos.

Etiquetas: swift opcionales protocolos Genéricos Estructuras

Publicado el 7-28 05:44