Tutorial Swift - Class y Struct (Aprende a programar apps para iOS)
Tutorial Swift - Class y Struct (Aprende a programar apps para iOS)

CLASS y STRUCT en Swift en Español - Curso Swift | Tutorial Swift

En Swift podemos usar Class o Struct para crear instancias de un tipo, cada una tiene sus características. Si estáis en algún proceso de selección os recomiendo leer este post por si os cae la típica pregunta de ¿cuáles son las principales diferencias entre una clase y un struct?

SwiftBeta

Tabla de contenido


👇 SÍGUEME PARA APRENDER SWIFTUI, SWIFT, XCODE, etc 👇
Aprende Swift desde cero

Las clases y structs las usamos en nuestras aplicaciones para un propósito más general. Podríamos decir que dentro de las clases y structs tenemos un conjunto de métodos y propiedades que siguen una misma lógica, es decir, dentro de cada clase tenemos métodos que tienen una responsabilidad común. En las clases y structs tenemos propiedades, que nos sirven para guardar el estado y también tenemos métodos que nos sirven para modificar ese estado.

Los métodos son funciones que están asociados a un tipo en particular

Comparando Class y Struct

Aunque se usan para propósitos diferentes, las dos tienen cosas en común:

  • Definir propiedades para almacenar valores.
  • Definir métodos que nos dan funcionalidad.
  • Definir subscripts para poder acceder a sus valores usando la sintaxis de los subscripts.
  • Definir inicializadores para setear un estado inicial.
  • Poder extender para añadir más funcionalidad.
  • Conformar protocolos para añadir más funcionalidad.

Pero las clases tienen cosas adicionales que no encontramos en structs

  • Podemos heredar solo usando clases.
  • Podemos deinicializar para liberar recursos.
  • Podemos tener una referencia de una clase almacenada en varias propiedades.

Al asignar una instancia de una clase a varias propiedades, éstas conservan la misma referencia. Si hacemos lo mismo para structs, se crea una copia de cada valor cada vez que la asignamos a una variable

Al definir una clase o struct, lo único que varía es que usamos class o struct seguido del nombre que queremos dar a nuestro nuevo tipo:

class SomeClass {
	// class definition goes here
}

struct SomeStructure {
	// structure definition goes here
}

En este caso las instancias se crean igual, y se acceden a las propiedas de la misma manera:

let someClass = SomeClass()
let someStruct = SomeStruct()

Inicializadores Memberwise para Struct

Cuando creamos una struct con sus propiedades no hace falta crear un init. Podemos usarlo automáticamente. En cambio en las clases sí que debemos crear el inicializador.

Al crear una struct no hace falta escribir el init pero en las clases sí.
class User {
    var name: String
    
    init(name: String) {
        self.name = name
    }
}

struct Coworker {
    var name: String
}

let user = User(name: "SwiftBeta")
let coworker = Coworker(name: "Swift") 

// No hace falta crear un init para la struct Coworker

¿Qué son Value Types?

Un value type es un tipo cuyo valor se copia cuando es asignado a una variable o constante, o cuando lo pasamos a una función. Las struct y los enum son value type, en cambio las clases son reference type, cuando tenemos una instancia de una clase y la asignamos a varias variables, cada variable apunta a la misma referencia en memoria.

¿Qué significa esto?

Cuando la instancia es compartida entre varias propiedades, si cambio el valor de una propiedad se cambia también en las demás, vamos a ver un ejemplo:

let user = User(name: "Swift")
var newUser = user

// Al cambiar el valor en newUser, el valor también cambia en user
newUser.name
newUser.name = "Beta"
user.name

En este caso hemos creado una copia de la referencia en newUser, al cambiar el name en newUser también se ha cambiado en user.

Podemos comparar cuando dos variables tienen la misma instancia de una clase, usando el operador ===

Si hacemos lo mismo con una struct (en lugar de una clase), la propiedad name no se vería afectada en user, sólo cambiaría la de newUser.

¿Cuándo usar Structs en Swift?

  • Un uso que le doy siempre a las structs es cuando trato con DataModels, Modelos, ViewModels, etc. Es decir, para tipos de datos simples, como por ejemplo: User.
  • Cuando todas las propiedades de una struct son value types como Int, String, Double, Enum, etc.
    Pero si usas una struct y tienes propiedades que son clases tienes que tener especial atención. En el siguiente snippet mostramos una struct y dentro, una propiedad que es una clase. Si tenemos una referencia de user fuera de la struct company y cambiamos alguna de sus propiedades, el cambio se ve reflejado dentro del struct:
class User {
    var name: String
    
    init(name: String) {
        self.name = name
    }
}

struct Company {
    var user: User
}

let user = User(name: "Swift")
let company = Company(user: user)

company.user.name // user name es Infinito
user.name = "Beta" // Al cambiar el valor name desde fuera de la struct, su valor se ve reflejado en company.user.name
company.user.name // En lugar de ser Swift, su nuevo valor es Beta
  • Al copiarse los valores cada vez que se asignan a una variable, no tenemos problemas de acceder a la misma referencia desde dos hilos distintos. Es más costoso copiar el valor pero es más seguro.
A medida que añadamos más posts al blog quedará más claro en qué momento usar class o struct. Lo importante es que sepas que existen y las diferencias que hay.