Aprendiendo Go

Publicado

Estoy tomando el tour de go y estoy sacando los siguientes apuntes:

Para instalar el compilador hay que descargar el paquete para tu sistema y extraerlo en /usr/local. Si es la primera vez se puede omitir el comando rm que elimina una instalación previa en caso de actualización. Tuve que ejecutar con sudo.

rm -rf /usr/local/go && tar -C /usr/local -xzf go1.22.0.linux-amd64.tar.gz

Agregué esta entrada a ~/.profile para que mi usuario pueda ejecutar go y luego reinicié.

export PATH=$PATH:/usr/local/go/bin

La estructura básica de un archivo de go define el paquete al que pertenece el script, los paquetes que se importan y un método main que es desde donde inicia la ejecución.

package main

import (
	"fmt"
	"time"
)

func main() {
	// hola mundo!
	fmt.Println("Hello world")
	//asigna variable e imprime
	now := time.Now()
	fmt.Println("Today is " + now.String())
	//ejecuta suma
	fmt.Println(suma(42, 13))
}

// función que suma dos números y regresa int
func suma(x int, y int) int {
	return x + y
}
package main

import (
	"fmt"
	"math/cmplx"
)

//bloque de constantes
const (
	bandera bool   = false
	maxInt  uint64 = 1<<64 - 1
)

//bloque de variables
var (
	z   complex128 = cmplx.Sqrt(-5 + 12i)
	empty string
)

// regresa más de un resultado
func swap(x, y string) (string, string) {
	return y, x
}

//naked return, las variables se declaran en la firma de la función
func split(sum int) (x, y int) {
	x = sum * 4 / 9
	y = sum - x
	return
}

func main() {
	// := es una forma corta de declarar e inicializar una variable, solo se puede usar dentro de funciones, fuera hay que usar var
	a, b := swap("hello", "world")
	fmt.Println(a, b)
	fmt.Println(split(17))
	// asignación múltiple
	var c, python, java = true, false, "no!"
	fmt.Println(c, python, java)
	// impresión de constantes y variables
	fmt.Println(bandera, maxInt, empty, z)
	// conversión entre tipos
	var i int = 42
	var f float64 = float64(i)
	var u uint = uint(f)
	fmt.Println(i, f, u)
}

Los tipos básicos son:

Ciclos y condicionales

package main

import (
	"fmt"
	"math"
	"runtime"
	"time"
)

func main() {
	// defer pospone la ejecución de la función hasta que la función que la contiene regrese
	defer fmt.Println("world")
	// for no lleva paréntesis
	sum := 0
	for i := 0; i < 10; i++ {
		sum += i
	}
	fmt.Println(sum)
	// no existe while, se usa for. Si no lleva condición es un bucle infinito.
	for sum < 1000 {
		sum += sum
	}
	// el if tampoco lleva paréntesis
	if sum > 1000 {
		fmt.Println("Mayor que 1000: ", sum)
	} else {
		fmt.Println("Menor que 1000: ", sum)
	}
	// pow
	fmt.Println(
		pow(3, 2, 10),
		pow(3, 3, 20),
	)
	//ejemplo switch, todo lleva break implícito
	switch os := runtime.GOOS; os {
	case "darwin":
		fmt.Println("OS X.")
	case "linux":
		fmt.Println("Linux.")
	default:
		fmt.Printf("%s.\n", os)
	}
	//switch sin condición espera true
	t := time.Now()
	switch {
	case t.Hour() < 12:
		fmt.Println("Good morning!")
	case t.Hour() < 17:
		fmt.Println("Good afternoon.")
	default:
		fmt.Println("Good evening.")
	}
	//los defer se ejecutan último en entrar primero en salir
	for i := 0; i < 10; i++ {
		defer fmt.Println(i)
	}
	//previo a defer
	fmt.Println("hello")
}

func pow(x, n, lim float64) float64 {
	// la variable v solo existe en el ámbito del if
	if v := math.Pow(x, n); v < lim {
		return v
	}
	return lim
}