Swift #14: Estructuras

Swift #14: Estructuras

Publish Date: Dec 15
0 0

Una estructura es un tipo de dato complejo que encapsula datos (variables y constantes, también llamados propiedades, miembros o atributos) y comportamiento (métodos). Las instancias de una estructura son únicas.

Atributos

Los atributos de una estructura se pueden definir de forma explícita (i.e. var nombre: Tipo = valor) o dejar que Swift infiera el tipo (i.e. var nombre = valor).

struct Person {
  var name: String = "David"
  var age: Int = 10
}

var instance1 = Person()
Enter fullscreen mode Exit fullscreen mode

La instancia es creada por el inicialiador de Person (i.e. Person() o Person.init()) y asignada a la variable instance1.

Para acceder a un atributo se usa la notación punto, como en instancia.propiedad, donde instancia es el nombre de la variable que contiene la instancia de la estructura y propiedad es el nombre de la propiedad que se quiere acceder.

struct Person {
  var name = "David"
  var age = 10
}

var instance1 = Person()
instance1.age = 11
print("Persona: \(instance1.name)")
Enter fullscreen mode Exit fullscreen mode

Para modificar los valores de una estructura se requiere que los atributos de la estructura sean variables (e.g. var name, var age). Además de eso, la instancia de la estructura también debe ser variable (e.g. var instance1) porque al modificar una variable, en realidad el sistema crea una nueva estructura con los nuevos valores, que luego reemplaza por la instancia inicial.

Métodos

Una función definida dentro de una estructura se llama método.

La sintaxis para invocar un método es: instancia.metodo() donde instancia es el nombre de la variable que contiene la instancia de la estructura y metodo() es el nombre del método que se quiere invocar sobre esa instancia. Por ejemplo:

struct Person {
  var name = "David"
  var age = 10
  func saludar() {
    print("Hola, soy \(name) y tengo \(age) años")    
  }
}

var instance1 = Person()
instance1.age = 11
instance1.saludar()
Enter fullscreen mode Exit fullscreen mode

Gracias a los métodos, no es necesario conocer los detalles del comportamiento definido en él, ni tampoco es necesario extraer la información de los atributos de la estructura. Simplemente se le pasan los argumentos que hagan falta y se deja a la instancia hacer el trabajo.

Para cambiar los valores de una estructura con un método, se lo debe modificar con la palabra clave mutating. Por ejemplo:

struct Person {
  var name = "David"
  var age = 10
  func saludar() {
    print("Hola, soy \(name) y tengo \(age) años")    
  }
  mutating func crecer() {
    age += 1
  }
}

var instance1 = Person()
instance1.age = 11
instance1.crecer()
instance1.saludar() // Hola, soy David y tengo 12 años
Enter fullscreen mode Exit fullscreen mode

Propiedades computadas

Las variables almacenadas almacenan un valor en memoria. En cambio, las variables computadas no almacenan nada sino que ejecutan alguna operaciones sobre las variables computadas leyendo o modificando sus valores.

Para modificar y extraer el valor de una variable computada se usan los métodos set y get, respectivamente. Solo get es obligatorio.

struct Person {
  var name = "David"
  var age = 10
  var nextAge {
    get {
      age + 1
    }
  }
}
let person1 = Person()
person1.nextAge // 11
Enter fullscreen mode Exit fullscreen mode

Las variables computadas son como métodos porque calculan su valor cada vez que se lee la propiedad.

Propiedad computada de solo-lectura

Cuando una propiedad computada solo tiene el getter (i.e. get), se dice que es de solo lectura, y podemos omitir la firma del método get.

struct Person {
  var name = "David"
  var age = 10
  var nextAge {
    age + 1
  }
}
let person1 = Person()
person1.nextAge // 11
Enter fullscreen mode Exit fullscreen mode

Propiedad computada de lectura y escritura

Al agregar el setter, set, se puede modificar el estado de la estructura al cambiar el valor de la variable computada. El nuevo valor de la variable computada se llama newValue. En caso de necesitar usar un nombre diferente de newValue se puede especificar entre paréntesis.

struct Person {
  var name = "David"
  var age = 10
  var nextAge {
    get {
      age + 1
    }
    set {
      age = newValue - 1
    }
  }
  var previousAge {
    get { age - 1 }
    set(previous) {
      age = previous + 1
    }
  }
}
let person1 = Person()
person1.nextAge // 11
Enter fullscreen mode Exit fullscreen mode

Property-observers

Los "Property-observers" informan del cambio de una propiedad de una estructura. Estos observadores son métodos especiales, similar a get y set que se pueden incluir en una propiedad para ejecutar código antes (willSet) y después (didSet) de que haya cambiado.

Dentro de willSet hay un parámetro llamado newValue con el valor que va a ser asignado a la propiedad. Por su parte, en didSet, el parámetro oldValue es el valor de la propiedad antes de ser modificado.

struct Person {
  var name = "David"
  var age = 10 {
    willSet {
      print("La nueva edad será: \(newValue)")
    }
    didSet {
      print("La edad era: \(oldValue) y ahora es: \(age)")
    }
  }
}
let person1 = Person()
person1.age = 11
// La nueva edad será: 11
// La edad era: 10 y ahora es: 11
Enter fullscreen mode Exit fullscreen mode

Tipos de datos primitivos como estructuras

Todos los tipos de datos primitivos de Swift están definidos como estructuras.

Cada vez que asignamos un nuevo valor a una variable de tipo primitivo, estamos asignando una estructura que contiene dicho valor.

Por ejemplo, la sintaxis variable: Int = value se traduce en variable = Int(value).

var myInt = Int(25)
var myDouble = Double(4.99)
Enter fullscreen mode Exit fullscreen mode

Las estructuras definidas para los tipos de datos primitivos también tienen sus propias propiedades y métodos estáticas. Por ejemplo, estas son algunas de las propiedades y métodos más usados:

  1. Int.min: Retorna el valor mínimo que puede manejar el tipo de dato.
  2. Int.max: Retorna el valor máximo que puede manejar el tipo de dato.
  3. Int.random(in: Range): Retorna un número aleatorio, entre un rango.
  4. .negate(): Invierte el signo.
  5. .isMultiple(of: Int): Retorna true si el valor es múltiplo del argumento.
  6. Double.pi: Constante pi.
  7. Double.inifinity: Retorna un valor muy grande.
  8. Double.random(in: Range): Retorna un valor aleatorio.
  9. .squareRoot: Raíz cuadrada
  10. .remainder(dividingBy: Double): Residuo de la operación
  11. .rounded(FloatingPointRoundingRule): Redondear un número.

Comments 0 total

    Add comment