Hola mundo en Go
Introducción al Curso de Golang
¿Qué es, por qué y quienes utilizan Go?
Instalar Go en Linux
Instalar Go en Mac
Instalar Go en Windows
Nuestras primeras lÃneas de código con Go
Variables, funciones y documentación
Variables, constantes y zero values
Operadores aritméticos
Tipos de datos primitivos
Paquete fmt: algo más que imprimir en consola
Uso de funciones
Go doc: La forma de ver documentación
Estructuras de control de flujo y condicionales
El poder de los ciclos en Golang: for, for while y for forever
Operadores lógicos y de comparación
El condicional if
Múltiple condiciones anidadas con Switch
El uso de los keywords defer, break y continue
Estructuras de datos básicas
Arrays y Slices
Recorrido de Slices con Range
Llave valor con Maps
Structs: La forma de hacer clases en Go
Modificadores de acceso en funciones y Structs
Métodos e interfaces
Structs y Punteros
Stringers: personalizar el output de Structs
Interfaces y listas de interfaces
Concurrencia y Channels
¿Qué es la concurrencia?
Primer contacto con las Goroutines
Channels: La forma de organizar las goroutines
Range, Close y Select en channels
Manejo de paquetes y Go Modules
Go get: El manejador de paquetes
Go modules: Ir más allá del GoPath con Echo
Modificando módulos con Go
Despedida del curso
Despedida
Bonus
Cheat Sheet Go
LibrerÃas para desarrollo web con Go
Data Science con Go
Aún no tienes acceso a esta clase
Crea una cuenta y continúa viendo este curso
Aportes 15
Preguntas 5
Tuve que ver un par de veces la clase para entender, aquà comparto el código con comentarios con la finalidad de que quede un poco mas claro el tema 😃 espero les sea de ayuda.
Peguen el codigo en VSCode para una mejor legibilidad jeje
package main
import (
"fmt"
"sync"
"time"
)
func say(text string, wg *sync.WaitGroup) { // Gorutine
defer wg.Done() // Esta linea se va a ejecutar hasta el final de la funcion, y de esta forma libera el gorutine del WaitGroup
fmt.Println(text)
}
func main22() {
var wg sync.WaitGroup // El paquete sync permite interacturar de forma primitiva con las gorutine. Variable que acomula un conjunto de gorutines y los va liberando poco a poco
fmt.Println("Hello")
wg.Add(1) // Indicamos que vamos a agregar 1 Gorutine al WaitGroup para que espere su ejecucion antes de que la gurutine base (main) muera, y asà le de tiempo a la siguiente gorutine de ejecutarse
go say("world", &wg) // la palabra reservada go ejecutará la funcion de forma concurrente
wg.Wait() // Funcion del WaitGroup que sirve para decirle al gorutine principal (main) que espere hasta que todas las gorutine del WaitGroup finalicen, es decir, hasta que se ejecute 'defer wg.Done()' en cada una de las goroutines
go func(text string) { // Funciona anonima
fmt.Println(text)
}("Adios")
time.Sleep(time.Second * 1) // ! Funcion para que cuando llegue a esta linea espere el tiempo indicado (lo suficiente para que la Gorutine ejecute su funcion de forma concurrente)
// Nota: Para fines practicos se hace uso de la funcion Sleep(), pero en realidad NO es una buena practica, es mejor utilizar los WaitGroups
}
Me costó un poco de trabajo entender esta clase. Asà que aquà va mi aporte:
Un WaitGroup espera a que una colección de goroutines termine su ejecución.
Para esto se una la WaitGroup.Add() ( wg.add(1) en el ejemplo de la clase).
El número entero indica el número de goroutines que debe esperar para finalizar la ejecución de la goroutine principal.
Cada vez que una goroutine termina su ejecución, llama el método Done(). Esto hace que el contador del WaitGroup se reduzca.
Cuando el contador llegue a zero la rutina principal continuará su ejecución.
La función wait() bloquea la rutina principal hasta que todas las demás rutinas del grupo hayan terminado.
💡 La concurrencia es un paradigma que indica la manera de ejecución de algunos procesos.
.
Podemos denotar 2 aspectos importantes en este tema:
.
En este punto, JavaScript se ve vulnerable porque la concurrencia no es uno de sus fuertes y por ello, pudiera romper el concepto a algunos.
.
💡 Un hilo, es una lÃnea de ejecución de algún proceso que fundamentalmente no es ni sincrónico, ni asincrónico.
.
Mencionamos que la concurrencia es un paradigma ya que nos permite realizar procesos delegados según sea SO, su peso o prioridad.
.
Les dejo un ejemplo para que evalúen la concurrencia desde otro enfoque.
No agregaste un wg.Add(1)
para la función anónima. Esto quiere decir que si usamos Gorutines con funciones anónimas no es necesario hacer uso de WaitGroup?
Es algo muy muy similar al asincronismo en JavaScript
[https://www.youtube.com/watch?v=bWvnWhVCHAc]( Asincronismo Platzi – Freddy Vega)
🤯
Mi ejercicio para practicar
package main
import (
"fmt"
"sync"
)
func mostrar(a int, wg *sync.WaitGroup) {
fmt.Println(a)
wg.Done()
}
func main() {
var slice = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
var wg sync.WaitGroup
wg.Add(len(slice))
for i := range slice {
go mostrar(i, &wg)
}
wg.Wait()
}
package main
import (
"fmt"
"sync"
"time"
)
func say(text string, wg *sync.WaitGroup) {
defer wg.Done()
fmt.Println(text)
}
func main() {
var wg sync.WaitGroup
fmt.Println("Hello")
wg.Add(2)
go say("world", &wg)
go say("!", &wg)
wg.Wait()
go func(text string) {
fmt.Println(text)
}("Adios")
time.Sleep(time.Second * 1)
}
En mis palabras, concurrencia y paralelismo. Espero que les sea de ayuda.
La concurrencia es el conjunto de mecanismos por los cuales podemos correr varios procesos o hilos de ejecución al mismo tiempo. Por ejemplo, tener varios núcleos en el procesador y que cada uno se encargue de un proceso, o dando un cachito de tiempo a cada proceso de forma intercalada (multiplexación en el tiempo). Incluso, podemos pensar la concurrencia a nivel de un conjunto de máquinas, cada una ejecutando programas diferentes que se comunican entre sÃ.
El paralelismo, por otro lado, es dividir un problema en varias partes y resolver cada una en simultáneo. Al final, podemos usar cada uno de los resultados para crear una solución al problema original (forkJoin).
Si encuentran alguna mejora, háganme saber.
MI Codigo comentado.
package main
import (
"fmt"
"sync"
"time"
)
func say(text string, wq *sync.WaitGroup) {
defer wq.Done()
fmt.Println(text)
}
func main() {
//sync.WaitGroup nos permitira agrupar las GoRutines y les difinira un tiempo determinado dentro de el hilo del nucleo como concurrencia.
var wq sync.WaitGroup
fmt.Println("Hello")
//Se anexa la informacion de las GoRutines que se agruparan junto con la GoRutine Main.
wq.Add(1)
//El tiempo de la ejecucion de una GoRutine Adicional se tomara como un tiempo extra, que la funcion main no esperara.
go say("World", &wq)
//Justo despues de que se este ejecutando la funcion say, la funcion main estara sobre la linea de codigo 24.
wq.Wait()
//con este atributo le diremos a la funcion main que espere, hasta que el atributo .Done(Linea 10) en la funcion ejecutada en una GoRutine adicional,se ejecute.
//Una vez ejecutada, la funcion main finalizara.
fmt.Println("Ha finalizado. :)")
// Tambien Podremos ejecutar dentro de una GoRutine adicional, funciones anonimas.
go func(text string) {
fmt.Println(text)
}(":) ahora sÃ, adios.")
//Este time.sleep le esta dando tiempo a que la GoRutine adicional, que contine la funcion anonima, se ejecute.
time.Sleep(time.Second * 1)
}
:3
Brutal.
Este es un tema algo confuso, hice una versión un poco más resumida del código de la clase, espero que les sirva! c:
func main() {
// Creamos un WaitGroup de esta forma
var waitGroup sync.WaitGroup
// Imprimimos en el runtime de main
fmt.Println("Hola")
// Indicamos al WG que agregaremos una rutina
// (incrementa el contador interno del WG en 1)
waitGroup.Add(1)
// Imprimimos usando una go routine, pasando el
// pointer al WG como argumento dentro de una función
// anónima. Se recomienda siempre usar funciones al
// implementar un WG. El keyword "go" indica la lÃnea
// que se ejecutará de forma concurrente usando Go Routines
go func (text string, localWG *sync.WaitGroup) {
// Esto indica que la Go routine ha terminado y
// reduce el contador interno del WG en 1. Usamos defer
// para que se ejecute al final de la ejecución de la
// función anónima
defer localWG.Done()
fmt.Println(text)
}("mundo", &waitGroup)
// Por último, antes que finalice main, usamos el WG para
// indicarle a Go que debe esperar a que todas las rutinas
// terminen. Es decir, que el contador interno regrese a 0.
waitGroup.Wait()
}
Interesante
El asincronismo esta conquistando el mundo.
¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.