Contenido del curso
Programación orientada a objetos
- 5

Programación Orientada a Objetos en Go: Análisis y Comparativa
06:51 min - 6

Equivalente de Clases en Go: Uso de Structs y Propiedades
06:41 min - 7

Métodos en Structs: Implementación de Receiver Functions en Go
08:54 min - 8

Implementación de Constructores en Go: Ejemplos y Mejores Prácticas
10:48 min - 9

Herencia y Composición en Programación Orientada a Objetos
14:50 min - 10

Interfaces y Polimorfismo en TypeScript y Go
12:35 min - 11

Patrón Abstract Factory: Interfaces y Polimorfismo en Go
07:37 min - 12

Implementación del Patrón Factory en Go para Notificaciones
10:10 min - 13

Funciones Anónimas en Go: Uso y Consideraciones Prácticas
06:56 min - 14

Funciones Variádicas y Retornos con Nombre en Go
10:51 min
Go Modules
Testing
- 17

Tests unitarios y code coverage en Go
10:47 min - 18

Cobertura de Código y Testing en Go: Mejorando la Calidad del Software
09:56 min - 19

Profiling de Código en Go para Optimización de Rendimiento
08:46 min - 20

Testing Unitario en Go: Uso de Mock Services
11:51 min - 21

Testeo Unitario de Funciones con MOOC en Go
08:53 min
Concurrencia
- 22

Canales con y sin buffer en Go: diferencias y uso práctico
06:23 min - 23

Sincronización de Rutinas en Go con Wait Group
07:26 min - 24

"Uso de Canales con Buffer como Semáforos en Go"
09:00 min - 25

Manejo de Canales de Lectura y Escritura en Go
09:34 min - 26

Concurrencia en Go: Creación de Worker Pools y Fibonacci
11:23 min - 27

Multiplexación de Canales en Go con Select y Case
07:13 min
Proyecto: servidor con worker pools
Conclusión
Go Routines, Canales y Apuntadores en Golang
Resumen
Comprender cómo funcionan las goroutines, los canales y los apuntadores es fundamental para escribir programas concurrentes y eficientes en Go. A continuación se explican estos tres pilares con ejemplos prácticos extraídos directamente del código trabajado en la sesión.
¿Por qué una goroutine no imprime nada si no usamos canales?
Una goroutine se crea anteponiendo la palabra reservada go antes de la llamada a una función [0:18]. En el ejemplo se define una función llamada doSomething que pone a dormir el proceso durante tres segundos con time.Sleep y luego imprime done.
go func doSomething() { time.Sleep(3 * time.Second) fmt.Println("done") }
Al invocarla con go doSomething(), la función se ejecuta en una rutina diferente a la de main [0:33]. El problema es que main no espera a que doSomething termine: el programa finaliza antes de que pasen los tres segundos y el mensaje done nunca aparece en pantalla [0:48].
¿Cómo se comunican goroutines mediante canales?
Para resolver este problema se emplea un canal (channel). Un canal permite enviar y recibir valores entre goroutines, actuando como mecanismo de sincronización [1:02].
- Se crea un canal de tipo entero:
c := make(chan int). - Se modifica
doSomethingpara que reciba ese canal como parámetro. - Dentro de la función se envía un valor al canal con el operador
<-:c <- 1[1:22]. - En
main, la lectura del canal (<-c) bloquea la ejecución hasta que el mensaje llegue [1:32].
go func doSomething(c chan int) { time.Sleep(3 * time.Second) fmt.Println("done") c <- 1 }
func main() { c := make(chan int) go doSomething(c) <-c }
Al ejecutar el programa, los tres segundos transcurren y el done se imprime correctamente [1:42]. La lección clave es que crear una goroutine no basta; se necesita un canal u otro mecanismo para coordinar la comunicación entre rutinas [1:55].
¿Qué diferencia hay entre un apuntador y un valor en Go?
Un apuntador (pointer) almacena la dirección de memoria de otra variable en lugar de su valor directo [2:08].
¿Cómo se crean y se leen apuntadores?
Se declara una variable g con valor 25. Para obtener su apuntador se utiliza el operador ampersand (&) [2:18]:
go g := 25 h := &g fmt.Println(h) // imprime la dirección de memoria, por ejemplo 0xc0000b4008
Si se imprime h directamente, Go muestra la dirección de memoria donde está alojado g [2:38]. Para acceder al valor real almacenado en esa dirección se usa el operador asterisco (*) [2:50]:
go fmt.Println(*h) // imprime 25
&g: devuelve la referencia (dirección de memoria) deg.*h: devuelve el valor almacenado en la dirección a la que apuntah.
Confundir estos dos operadores puede provocar errores difíciles de rastrear, por lo que conviene tener claro cuándo se trabaja con la dirección y cuándo con el valor [3:08].
¿Qué sintaxis esencial conviene recordar?
Estos son los elementos revisados y su propósito:
go+ función: lanza una goroutine.make(chan tipo): crea un canal del tipo indicado.canal <- valor: envía un dato al canal.<-canal: recibe un dato del canal y bloquea hasta obtenerlo.&variable: obtiene el apuntador (dirección de memoria).*apuntador: accede al valor almacenado en la dirección.
Dominar estos fundamentos prepara el camino para temas más avanzados como la programación orientada a objetos en Go, que es justamente lo que sigue en el curso [3:30]. Si alguno de estos conceptos te generó dudas, comparte tu experiencia en los comentarios.