# Go desde Cero, Introducción

Go desde Cero, Introducción
Tabla de Contenidos

🧩 Módulo 1, Capitulo 1: Fundamentos con cerebro

Bueno muchachones, este primer módulo es la base de todo.!!! No vamos a correr, vamos a construir bien. Entender el ” porqué” de Go, te dará una ventaja brutal para dominarlo de verdad, no solo para escribir código que “funciona”.


A ver!!! Qué es Go y por qué fue creado???

Go (o Golang) no nació por capricho. Nació en Google alrededor de 2007, de la mente de tres gigantes de la computación: Robert Griesemer, Rob Pike y Ken Thompson. Sí, ese Ken Thompson panas mios, uno de los creadores de Unix y del lenguaje C. Pura gente que sabía lo que hacía.!!!

El Problema que Resolvía

A mediados de los 2000, Google se enfrentaba a un monstruo que ellos mismos habían creado: una base de código masiva, miles de ingenieros trabajando a la vez y sistemas que necesitaban procesar terabytes de datos de forma concurrente, una verdadera locura!!!

Los lenguajes que usaban (principalmente C++ y Java) empezaban a mostrar sus costuras:

  • Tiempos de compilación eternos: Compilar el software de Google podía llevar horas. Esto mataba la productividad. Un desarrollador hacía un pequeño cambio y tenía que esperar una eternidad para probarlo. Todo un beta!!! (como decimos en Venezuela hahaha)

  • Complejidad abrumadora: Lenguajes como C++ tienen una cantidad enorme de características. Esto lleva a código complejo, difícil de leer y mantener por equipos grandes. Si me volvia loco en la univ!!! No me quiero imaginar esas bases de codigo :S

  • Concurrencia difícil y peligrosa: Aunque existían los hilos (threads), manejarlos era un infierno. Errores como race conditions o deadlocks eran el pan de cada día y muy difíciles de depurar.

  • Gestión de dependencias caótica: No había una forma estándar y limpia de manejar las librerías y paquetes.

Go fue la respuesta a este dolor. Se diseñó con una filosofía clara: ser simple, eficiente y excelente en la concurrencia.

La Solución Go

  • Compilación ultra-rápida: El lenguaje se diseñó desde cero para compilar a la velocidad de la luz. Esto devuelve la agilidad al desarrollador.

  • Sintaxis minimalista: Go tiene muy pocas palabras clave. Es un lenguaje “aburrido” a propósito. La idea es que el código sea fácil de leer y predecible, sin dobles sentidos ni magia negra.

  • Concurrencia como ciudadano de primera clase: Go integra la concurrencia en el núcleo del lenguaje con las * goroutines* y los channels. Hacen que escribir código concurrente sea trivialmente fácil y, sobre todo, seguro.

  • Un binario estático: Al compilar, Go genera un único archivo ejecutable que contiene todo lo necesario para correr (el programa, el runtime de Go, las librerías). ¡Se acabó el “en mi máquina funciona”! Simplemente copias el binario al servidor y listo.

En resumen muchachones, Go fue creado para la ingeniería de software a gran escala. Es un lenguaje pragmático, hecho por ingenieros para ingenieros, con el objetivo de escribir software robusto, mantenible y de alto rendimiento de la forma más sencilla posible.


Cómo compila y administra memoria Go

Bueno caballeros, Entender esto es clave para no usar Go como si fuera Python o Java (Sorry mi querido y amado lenguaje). Su poder reside en cómo gestiona los recursos de la máquina.

El Proceso de Compilación

Cuando ejecutas el comando go build, suceden varias cosas, pero de forma increíblemente rápida:

  1. Análisis de dependencias: Go analiza tu código para ver qué paquetes necesita (tanto de la librería estándar como de terceros).

  2. Compilación por paquete: Compila cada paquete de forma independiente y en paralelo, aprovechando todos los núcleos de tu CPU.

  3. Enlazado (Linking): El “linker” de Go une todo el código compilado: tu programa, las librerías necesarias y el * runtime de Go*.

  4. Resultado: un binario nativo. El archivo final es código máquina que el sistema operativo puede ejecutar directamente, sin necesidad de una máquina virtual (como la JVM de Java) o un intérprete (como en Python). Esto es uno de los secretos de su velocidad de ejecución.

Esta compilación estática es la razón por la que los contenedores Docker con aplicaciones Go son tan ligeros. A menudo, solo necesitas una base mínima (como Alpine o incluso scratch) y tu binario.

Administración de Memoria: El Garbage Collector (GC)

Go gestiona la memoria por ti. No tienes que hacer malloc ni free como en C (olvidate de esa tortura). Lo hace a través de un componente llamado Garbage Collector (Recolector de Basura).

Pero el GC de Go es especial y está diseñado para sistemas de baja latencia (como las APIs que deben responder en milisegundos).

Cómo funciona a grandes rasgos???

  1. Asignación en el Heap: Cuando creas objetos complejos (structs, slices, etc.), Go los almacena en una zona de memoria llamada heap.

  2. El problema: Con el tiempo, algunos de esos objetos ya no se usan. Si no se limpiaran, la memoria del programa se agotaría (esto se llama memory leak).

  3. El Recolector al Rescate: El GC de Go se ejecuta periódicamente en segundo plano. Su trabajo es encontrar qué objetos en el heap ya no son accesibles desde ninguna parte del programa (por ejemplo, una variable que solo existía dentro de una función que ya terminó).

  4. Pausas Mínimas: Los recolectores de basura tradicionales tenían un gran problema: para hacer su trabajo, debían ” congelar” el programa por completo durante un instante (esto se llama Stop-The-World o STW). En Go, el recolector está diseñado para que estas pausas sean extremadamente cortas, a menudo por debajo del milisegundo. Lo logra haciendo la mayor parte de su trabajo de forma concurrente con tu propio código, minimizando el tiempo en que necesita detener todo.

Esta eficiencia en la gestión de memoria y las pausas casi imperceptibles del GC hacen que Go sea ideal para servicios de backend de alto rendimiento, donde una pausa larga podría significar la pérdida de peticiones de usuarios.


El ADN del Código

Bueno, ya sabemos por qué existe Go. Ahora vamos a ver cómo sus decisiones de diseño más básicas, como el manejo de una simple variable, ya sientan las bases de la robustez y la eficiencia.

Tipado Fuerte y Estático: Tu Red de Seguridad

Go es un lenguaje de tipado estático y fuerte. Esto no es un capricho académico, es una de las decisiones más importantes para garantizar la fiabilidad del software.

  • Estático (Static Typing): Significa que el tipo de una variable se conoce en tiempo de compilación. Antes de que tu programa se ejecute, el compilador de Go ya ha verificado cada una de tus variables y se ha asegurado de que las operaciones que haces con ellas son válidas.

    • El Problema que Evita: En lenguajes de tipado dinámico (como Python o JavaScript), un error de tipo solo se descubre cuando el programa se ejecuta y llega a esa línea de código. TypeError: 'NoneType' object is not iterable… te suena??? Esto puede ocurrir en producción, días después de haber desplegado (me paso njda). En Go, ese error ni siquiera te dejaría compilar.

    • Cómo Funciona por Debajo: Cuando declaras miVariable int, le estás diciendo al compilador: “Reserva un espacio en memoria para esta variable, y asegúrate de que sea exactamente del tamaño de un entero (ej. 64 bits en un sistema de 64 bits)”. El compilador “etiqueta” esa variable y, a partir de ese momento, vigilará que solo intentes guardar enteros en ella. Si intentas asignarle un texto, el compilador levantará una bandera roja y detendrá la compilación. Esto no solo previene errores, también optimiza el rendimiento, porque el programa no tiene que adivinar el tipo de dato en tiempo de ejecución.

  • Fuerte (Strong Typing): Significa que Go no hará conversiones de tipo “mágicas” o implícitas que puedan llevar a pérdida de datos o comportamientos inesperados.

    • El Problema que Evita: En algunos lenguajes, podrías sumar un número (10) y un texto que parece un número ( "5") y el lenguaje podría decidir por ti que el resultado es 15 o "105". Esta ambigüedad es peligrosa, es como en una pelea de MMA dejarle la decisión al réferi!!!

    • La Solución Elegante de Go: Go te obliga a ser explícito. Si tienes un entero (int) y un número de punto flotante (float64), no puedes sumarlos directamente. Debes convertir uno de los dos de forma explícita.

      var a int = 10
      var b float64 = 5.2
      // Esto NO compila: mismatched types int and float64
      // c := a + b
      // Esto SÍ compila: eres explícito sobre tu intención
      c := float64(a) + b

      Esto puede parecer verboso al principio, pero te fuerza a pensar en lo que estás haciendo y elimina una categoría entera de errores sutiles.

Declaración de Variables: Más que Asignar un Nombre!!!

En Go, declarar una variable no es solo ponerle una etiqueta a un valor. Es un contrato con el compilador.

Existen principalmente dos formas de declarar variables: la forma larga y la forma corta.

  1. Declaración Larga (var)

    var edad int = 30
    • Análisis Quirúrgico:
      • var: Palabra clave que le dice al compilador: “prepárate, voy a definir una nueva variable”.
      • edad: El nombre que le damos.
      • int: El tipo explícito. Aquí está el contrato del que hablábamos.
      • = 30: La inicialización (darle un valor inicial).

    Puedes omitir el valor inicial o el tipo (si el compilador puede inferirlo), pero la forma var es útil cuando quieres ser muy explícito o cuando declaras variables a nivel de paquete.

  2. Declaración Corta (:=) Conocido en los bajos fondos como el operador morsa hahaha

    nombre := "Alex"

    Esta es la forma más común y idiomática de Go dentro de las funciones.

    • Análisis Quirúrgico:
      • :=: Es el operador de declaración corta. Hace dos cosas a la vez: declara la variable (nombre) e * infiere* su tipo a partir del valor de la derecha ("Alex" es un string).
      • Cómo funciona por debajo: El compilador ve el valor "Alex", reconoce que es una cadena de texto y automáticamente le asigna el tipo string a la variable nombre. Es azúcar sintáctico para var nombre string = "Alex". Importante: solo se puede usar := dentro de funciones.

El Concepto del “Valor Cero” (Zero Value)

Esta es una de las características más geniales y simples de Go. En Go, no existen las variables no inicializadas.

  • El Problema que Resuelve: En C, si declaras int x; y no le asignas un valor, x contiene “basura”: el residuo de lo que sea que estuviera antes en esa posición de memoria. Usar esa variable puede llevar a comportamientos completamente impredecibles.

  • La Solución Elegante de Go: Si declaras una variable pero no le das un valor inicial, Go le asigna automáticamente un “valor cero” según su tipo muchachones.

    var cantidad int // Se inicializa a 0
    var precio float64 // Se inicializa a 0.0
    var activo bool // Se inicializa a false
    var titulo string // Se inicializa a "" (cadena vacía)
    var puntero *int // Se inicializa a nil (el equivalente a null para los que venimos de otros lenguajes)

    Por qué es esto tan importante??? Porque garantiza que tus variables siempre tengan un estado inicial predecible. Esto elimina toda una clase de bugs y hace el código más seguro y fácil de razonar. No tienes que inicializar cada variable por miedo a que contenga basura; puedes confiar en su valor cero por defecto.

Tipos de Datos Fundamentales (y su interior)

Ahora veamos los bloques de construcción básicos y qué son en realidad.

  • Enteros (int, uint, int8, int64, etc.):

    • Lo que ves: x := 100

    • Lo que es por debajo: Una secuencia de bits en memoria que representa un número. La diferencia entre int8, int16, int32 e int64 es simplemente cuántos bits se usan.

      • int8: Usa 8 bits. Puede almacenar números de -128 a 127.

      • int64: Usa 64 bits. Almacena un rango de números muchísimo mayor.

    • Dominio Real: Por qué elegir??? Eficiencia. Si estás procesando millones de datos y sabes que un valor nunca superará el 200, usar un int8 en lugar de un int64 (que suele ser el int por defecto) puede ahorrar una cantidad significativa de memoria. int y uint son especiales: su tamaño depende de la arquitectura de tu sistema (32 o 64 bits).

  • Booleanos (bool):

    • Lo que ves: esValido := true

    • Lo que es por debajo: Típicamente, un solo byte de memoria. Aunque un bit sería suficiente para true/ false, la memoria se direcciona por bytes. El valor es 1 para true y 0 para false. Sencillo, predecible, sin sorpresas.

  • Strings (string):

    • Lo que ves: mensaje := "Hola, Mundo"

    • Lo que es por debajo (Esto es CLAVE muchachones!!!): Un string en Go es inmutable y, en realidad, es una estructura (un struct) que contiene dos campos:

      1. Un puntero a una secuencia de bytes en memoria (el texto en sí, codificado en UTF-8).

      2. Un entero con la longitud de esa secuencia.

    • Por qué es inmutable??? Inmutabilidad significa que una vez que creas un string, no puedes cambiar su contenido. Si haces mensaje += "!", no estás modificando el string original. Estás creando un nuevo string en una nueva ubicación de memoria con el contenido combinado.

    • Dominio Real: Esta inmutabilidad es una bendición para la concurrencia. Si varios procesos (goroutines) leen el mismo string a la vez, no hay peligro de que uno lo modifique mientras otro lo está leyendo. Esto elimina la necesidad de bloqueos (mutexes) para proteger strings, haciendo el código más limpio y rápido. Es una decisión de diseño enfocada 100% en la seguridad en entornos concurrentes.

Mis muchachos, entender estos fundamentos te permite escribir código que no solo funciona, sino que es seguro, eficiente y coherente con la filosofía de Go. Cada decisión, desde el tipado estático hasta el valor cero, está ahí por una razón: ayudarte a construir mejor software.!!! Nos vemos en el siguiente articulo, donde continuaremos sentando las bases.. Activitos muchachones!!!

Next: Go desde Cero, Pero Bien: Anatomía de un Programa Go, Errores y Slices
Foto Cesar Fernandez

¿Lo rompiste? ¿Lo mejoraste?

Gracias por llegar hasta el final. Escribo estos posts para organizar mis propias ideas y, con suerte, para ahorrarle a alguien más el dolor de cabeza que yo ya pasé. Me encuentras en LinkedIn o puedes ver más de mi trabajo en GitHub.


Serie: Curso Profesional de Go