Saltar al contenido principal

Funciones

Introducción

Para declarar una función en golang, usar la palabra reservada func

  • Declaración:

    func miFuncion() {
    fmt.Println("hola mundo")
    }

    // Funciones
    func main() {
    miFuncion()
    }
  • Funcion con parametros

    func miFuncionConParametros(n1 int, n2 int) {
    resultado := n1 + n2
    fmt.Println(resultado)
    }
    • Debo declarar el tipo de dato del parametro.
      • Si trato de pasar como parametro otro tipo distinto al declarado
        • Muestra un error en el IDE
          miFuncionConParametros("2", 2)
  • Función con retorno

    • Debo declarar el tipo de dato a retornar
    func funcionConRetorno(nombre string) string {
    return "Tu nombre es " + nombre
    }
  • Funcion con varios retornos

    func funcionRetornoMultiple() (string, string, string) {
    return "Juan", "Pedro", "Pablo"
    }

    nombre1, nombre2, nombre3 := funcionRetornoMultiple()

Funciones anonimas

Función sin nombre que se declaran generalemente dentro de una variable.

var suma = func(numero1 int, numero2 int) int {
return numero1 + numero2
}

Funciones closure

Funciones que retornan otra función.

// Imprime la tabla de multiplicar
func tabla(valor int) func() int {
numero := valor
secuencia := 0

return func() int {
secuencia++
return numero * secuencia
}
}

Tabla := tabla(2)

for i := 1; i <= 10; i++ {
fmt.Printf("2 x %v = %v \n", i, Tabla())
}

// Salida:
// 2 x 1 = 2
// 2 x 2 = 4
// 2 x 3 = 6
// 2 x 4 = 8
// 2 x 5 = 10
// 2 x 6 = 12
// 2 x 7 = 14
// 2 x 8 = 16
// 2 x 9 = 18
// 2 x 10 = 20

Lo interesante de este funcionamiento es que la funcion tabla cuando se llama y luego retorna la función interna, esta guarda el estado de la variable secuencia la cual va aumentando en 1 en cada llamado.

GO Routines

Son funciones que permiten ser ejecutadas en hilos diferentes (channels).

Me permite pausar una ejecición o ponerla en un channel.

Supongamos esta función que muestra por pantalla un mensaje:

func miFuncionRoutine(parametro string) string {
return "hola " + parametro
}

Ahora simulemos con el paquete time pausar la aplicación 5 seg entre llamados de la función:

// Ejemplo con paquete time
msj := miFuncionRoutine("mundo")

fmt.Println(msj)

time.Sleep(time.Second * 5)

fmt.Println(miFuncionRoutine("cruel"))

//hola mundo
//hola cruel --> Pasaron 5 seg antes de mostrase este mensaje

Ahora veamos un ejemplo con channels:

func miFuncionRoutine(parametro string) string {
time.Sleep(time.Second * 5)
return "hola " + parametro
}

// Usando channels
miCanal := make(chan string)

go func() {
miCanal <- miFuncionRoutine("Pedro")
}()

fmt.Println("Continuar con la ejecución")
fmt.Println(<-miCanal)
fmt.Println("Termino la ejecución")

// Continuar con la ejecución
// hola Pedro
// Termino la ejecución

Recursividad

Llamar a una función dentro de si misma…

func miFuncionRecursiva(valor int) {
dato := valor + 1
fmt.Println(dato)

if dato < 10 {
miFuncionRecursiva(dato)
}
}

// Recursividad

func main() {
miFuncionRecursiva(0)
}

// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9
// 10

Defer y panic

  • Panic: Muestra un mensaje un error para detner la ejecución del sript con info detellada en la terminal (No son excepciones, go no las usa).
    func funcionPanic() {
    a := 1

    if a == 1 {
    panic("Fallo porque es igual a 1")
    }
    }

    // panic: Fallo porque es igual a 1

    // goroutine 1 [running]:
    // main.funcionPanic(...)
    // /home/julian/cursos/go/funciones/main.go:66
    // main.main()
    // /home/julian/cursos/go/funciones/main.go:74 +0x27
    // exit status 2
  • defer: Esto permite terminar la ejecución al final de la función.
    func miFuncionDefer() {
    defer fmt.Println("Este es el mensaje final")
    fmt.Println("Este es un primer mensaje")
    }

    // Este es un primer mensaje
    // Este es el mensaje final