Funciones
Función sin parámetros de entrada
func showMessage()->String{
return "welcome"
}
showMessage()
Función que recibe una variable name de tipo string y retorna un string
func sayHello(name: String) -> String{
let greet = "Hi \(name)"
return greet
}
sayHello(name: "Jhon")
Función que recibe 2 parámetros Int y retorna otro Int
func plus(number1 : Int, number2: Int)->Int{
let result = number1 + number2
return result
}
plus( number1: 5 , number2: 7 )
Función sin valor de retorno
func hi(name: String){
print("Hi \(name)")
}
hi(name: "Louis")
Función que retorna una tupla
func minMax(numeros:[Int])->(min: Int , max: Int){
var currentMin = numeros[0]
var currentMax = numeros[0]
for value in numeros{
if value < currentMin {
currentMin = value
}else if value > currentMax {
currentMax = value
}
}
return (currentMin, currentMax)
}
minMax(numeros: [5,2,6,8,6,2])
Misma función anterior, pero valida si es un array vació y el retorno de la tupla sera opcional (?)
func minMaxGood(numeros:[Int])->(min: Int , max: Int)?{
// Si es vacio, retorna nil
if( numeros.isEmpty){ return nil }
var currentMin = numeros[0]
var currentMax = numeros[0]
for value in numeros{
if value < currentMin {
currentMin = value
}else if value > currentMax {
currentMax = value
}
}
return (currentMin, currentMax)
}
minMaxGood(numeros: [])
Podemos definir etiquetas (alias) para 1 o mas parametros
func suma(n1 primerNumero : Int, n2 segundoNumero : Int){
// internamente usaremos primerNumero y segundoNumero
}
// Asi, usaremos las etiquetas al llamar a la función
suma(n1: 5 , n2 : 10)
Podemos omitir una o mas etiquetas
func saluda(_ name : String, from ciudad : String){
// use primerNumero and segundoNumero
}
saluda("Juan" , from: "Sidney")
Definir un parámetro por defecto
func saludaDeNuevo(_ name : String, from ciudad : String = "Santiago"){
// use primerNumero and segundoNumero
}
// Puede pasar solo el primer parametro, y usara el segundo con su valor predefinido
saludaDeNuevo("Oliver")
// o puede pasar ambos parámetros
saludaDeNuevo("Heriberto", from: "Italy")
Recibir una cantidad de parámetros no determinados
func promedio(_ numbers: Int... )-> Double{
var suma : Int = 0
for number in numbers {
suma += number
}
var promedio = Double(suma) / Double(numbers.count)
return Double(promedio)
}
promedio(2,2,3)
promedio(2,2,3,3,4,5,6,7)
Modificar parámetros fuera de la función
var intentos = 0
func notificar(_ contador : inout Int){
contador += 1
// hacer cosas
}
notificar(&intentos)
Definir función como variable
func resta(_ n1 : Int , _ n2 : Int) -> Int {
return n1-n2
}
var operacion : (Int, Int) -> Int = resta
operacion(5,7)
Funciones anidadas
func calculadora(_ operacion : String, _ n1 : Int , _ n2 : Int ) -> Int{
var resultado = 0
func suma()->Int{
return n1+n2
}
func resta()->Int{
return n1-n2
}
switch operacion {
case "suma":
resultado = suma()
case "resta":
resultado = resta()
default:
break;
}
return resultado
}
calculadora("suma", 1, 2)
calculadora("resta", 14, 1)
Closures
En palabras simples, un closure es una función anónima ( una función sin nombre ) que sera pasada como parámetro a otra función. Su sintaxis es algo así:
{ (params) -> return type in
//Código del closure
}
Un ejemplo pasando un closure al método sorted
de un array
// Opción 1
letrasReversas = letras.sorted(by: { (s1: String, s2: String) -> Bool in return s1>s2 })
// Opción 2
letrasReversas = letras.sorted(by: { s1, s2 in return s1>s2 })
// Opción 3
letrasReversas = letras.sorted(by: { s1, s2 in s1>s2 })
// Opción 4
letrasReversas = letras.sorted(by: { $0>$1 })
// Opción 5
letrasReversas = letras.sorted(by: >)
// Todas generan el mismo resultado, lo podemos imprimir, asi:
print(letrasReversas)
Ejemplo de closure en una función normal
// Definimos la función
func tarea1(closure: () -> Void){
// Aquí irían las instrucciones de tarea 1
print("instruccion 1 de la funcion tarea 1")
print("instruccion 2 de la funcion tarea 1")
// Llamamos al closure
closure()
}
// Llamando a la función y pasandole el closure como parámetro (sintaxis completa)
tarea1(closure: {
//Aquí iria el cuerpo del closure
print("instruccion en el closure")
})
// Llamando a la función y pasandole el closure como parámetro (sintaxis simplificada)
tarea1 {
//Añadir el closure aquí
print("instruccion en el closure")
}
Escapando un closure
// Variable en la que almacenaremos el closure
var closureAlmacenado : ()->Void = {};
// Definimos nuestra función
func tarea2 (closureRecibido: @escaping ()->Void){
print("instruccion 1 de la funcion tarea 2")
print("instruccion 2 de la funcion tarea 2")
// No ejecuta el closure, lo almacena en una variable de un scope superior
closureAlmacenado = closureRecibido
}
// Llamamos a nuestra función y le pasamos el closure
tarea2 {
print("Instrucción en closure async")
}
// Ejecutamos nuestro closure almacenado
closureAlmacenado()
Enumerados
Definir un enumerado
enum miEnumerado{
// Define los valores posibles
}
enum sexo{
case femenino
case masculino
case indeterminado
}
print(sexo.femenino)
// femenino
Ejemplo de uso de un enumerado
// Definimos el enumerado y sus casos
enum Barcode{
case upc(Int, Int, Int, Int)
case qrCode(String)
}
// Podemos definir el codigo de un item de tipo barcode respetando la estructura
var itemACode = Barcode.upc(8, 2346, 2365, 8)
print(itemACode)
// upc(8, 2346, 2365, 8)
// Podemos definir el código de un item de tipo qrCode respetando la estructura
var itemBCode = Barcode.qrCode("hgasjdgasj")
print(itemBCode)
//qrCode("hgasjdgasj")
// Respondemos según el tipo de código
switch itemACode {
case let .upc(n1 , n2, n3, n4):
print("Es UPC :\(n1) \(n2) \(n3) \(n4)")
// Es UPC :5 6534 62525 33
case let .qrCode(qrString):
print("Es QR: \(qrString)")
// Es QR: hgasjdgasj
}
Trabajando con rawValues
/**
Podemos asignar valores de referencia (rawValue) a cada caso
asignamos a mercury 2
y venus asume 3, y earth 4, respectivamente
*/
enum Planets: Int{
case mercury = 2
case venus
case earth
}
/**
Podemos consultar que rawValue tiene un caso
*/
print(Planets.earth.rawValue)
/**
Podemos consultar que valor tiene un rawValue
*/
if let planetOne = Planets(rawValue: 2){
print(planetOne)
}