Sintaxis GO
Contents
Sintaxis GO#

Sintáxis básica de GO
Índice
Elementos básicos del lenguaje#
Instalación#
Instalación:
sudo apt install golang
Extensión de archivos: .go
Comentarios#
Comentarios de una sola línea:
1// Esto es un comentario de una línea
Comentarios multilínea:
1/*
2Comentarios de
3tipo multilínea
4*/
Entrada y salida estandar#
Datos de entrada y salida a través de la consola y/o el navegador.
1package main
2
3import "fmt"
4
5func main(){
6 // declarar valor entrada:
7 var edad int
8
9 // salida estandar:
10 fmt.Print("¿Qué edad tienes?: ")
11
12 // entrada estandar:
13 fmt.Scan(&edad)
14
15 // impresión con salto de línea:
16 fmt.Println("Tienes", edad, "años")
17
18 // Introducir múltiples valores:
19 var nombre, apellidoUno, apellidoDos string
20
21 fmt.Print("¿Cómo te llamas?: ")
22 fmt.Scanf("%v %v %v", &nombre, &apellidoUno, &apellidoDos)
23
24 fmt.Printf("Te llamas %v %v %v", nombre, apellidoUno, apellidoDos)
25}
Estructura en GO#
Código GO puro:
1package main
2
3import "fmt"
4
5// Función principal:
6func main(){
7 // imprimir un saludo:
8 fmt.Println("Hola a full!")
9}
Concatenación#
Concatenación de variables y cadenas se realiza con +
1package main
2
3import "fmt"
4
5func main(){
6 nombre := "Guillermo"
7
8 // concatenar:
9 fmt.Println("Me llamo " + nombre)
10
11 // se puede ir agregando variables y dejará espacios:
12 fmt.Println("Hola", "amigo mío, tienes", 33, "años")
13
14 // impresión usando verbos:
15 nombre := "Guillermo"
16 apellidos := "Granados Gómez"
17 edad := 33
18
19 // cada %v devolverá el valor de una variable según el orden:
20 fmt.Printf("Te llamas %v %v y tienes %v años", nombre, apellidos, edad)
21}
GO-CLI - Comandos de GO#
Comandos de GO:
go version: versión de go instalada.
go build: se ejecuta en la raiz del proyecto para generar un ejecutable.
go build archivo.go: genera un ejecutable de un script.
GOOS=windows GOARCH=386 go build archivo.go: genera un ejecutable para otro sistema.
go run archivo.go: ejecuta un script de go.
godoc: Abre un servidor web en la dirección http://localhost:6000
go get: permite descargar bibliotecas y utilidades de terceros.
go mod: permite gestionar los proyectos locales.
go mod init nombre_proyecto
Atención
Para poder importar paquetes externos con go get antes hay que ejecutar el comando go mod init nombre_proyecto
Variables y tipos de datos#
Declaración, asignación y tipo:
1package main
2
3import "fmt"
4
5func main(){
6 // declaración, que se puede hacer así o de una vez:
7 var otroTexto string
8 otroTexto = "Soy otra cadena"
9 var numero int = -15
10 var numeroSinSimbolo uint = 15
11 var decimal float32 = 2.35
12 var decimalLargo float64 = 32.23423423
13 var booleano bool = true
14
15 // declaración múltiple:
16 var (
17 nombre = "Guillermo"
18 apellidos = "Granados Gómez"
19 edad = 34
20 )
21
22 fmt.Println("Soy", nombre, apellidos, "y tengo", edad, "años.")
23
24 // declaracion con operador de inicialización:
25 texto := "Cadena de texto \n - separada por una línea"
26
27 fmt.Println(otroTexto)
28}
Atención
Las variables declaradas deben usarse o dará error a la hora de compilar. Se recomienda también declarar en la medida de lo posible usando el operador :=
Constantes:
1package main
2
3import "fmt"
4
5func main(){
6 // definición de constante:
7 const PI = 3.1416
8 fmt.Println(PI)
9
10 // definir múltiples constantes:
11 const (
12 nombre = "Guillermo"
13 apellidos = "Granados Gómez"
14 edad = 33
15 )
16 fmt.Print(edad)
17}
Operadores#
Operadores aritméticos#
Operaciones aritméticas:
1package main
2
3import "fmt"
4
5func main(){
6 suma := 2 + 2
7 resta := 2 - 2
8 multiplicacion := 2 * 2
9 division := 2 / 2
10 resto := 2 % 2
11}
Incremento y decremento:
1package main
2
3import "fmt"
4
5func main(){
6 numero := 5
7
8 // incremento y decremento:
9 numero++
10 ++numero
11 numero--
12 --numero
13}
Asignar operación:
1 package main
2
3import "fmt"
4
5func main(){
6 numero := 5
7
8 numero += 10
9 numero -= 11
10 numero *= 2
11 numero /= 7
12 numero %= 2
13}
Operadores relacionales#
Validación entre dos números.
Mayor que: >.
Menor que: <.
Mayor o igual que: >=.
Menor o igual que: <=.
Igual que: ==.
Operadores lógicos#
Expresiones de operaciones lógicas.
and: &&.
or: ||.
not: !.
Estructuras de control#
Condicional if#
if sencillo:
1package main
2
3import "fmt"
4
5func main() {
6 var edad int
7
8 fmt.Print("¿Qué edad tienes? \n>>> ")
9 fmt.Scanln(&edad)
10
11 if edad >= 18 {
12 fmt.Println("Eres mayor de edad")
13 }
14}
if / else:
1package main
2
3import "fmt"
4
5func main() {
6 var edad int
7
8 fmt.Print("¿Qué edad tienes? \n>>> ")
9 fmt.Scanln(&edad)
10
11 if edad >= 18 {
12 fmt.Println("Eres mayor de edad")
13 } else {
14 fmt.Println("Todavía eres menor de edad")
15 }
16}
else-if:
1package main
2
3import "fmt"
4
5func main() {
6 var edad int
7
8 fmt.Print("¿Qué edad tienes? \n>>> ")
9 fmt.Scanln(&edad)
10
11 if edad >= 65 {
12 fmt.Println("Eres un anciano")
13 } else if edad >= 18 {
14 fmt.Println("Eres mayor de edad")
15 } else {
16 fmt.Println("Todavía eres menor de edad")
17 }
18}
if declaración corta:
1package main
2
3import "fmt"
4
5// crear una función para recibir parámetros:
6func calcula_edad(e int) string {
7 // asignar una variable al scope de un if:
8 if edad := e; edad >= 18 {
9 return "Eres mayor de edad"
10 } else {
11 return "Eres menor de edad"
12 }
13}
14
15func main() {
16 var mi_edad int
17
18 fmt.Println("¿Qué edad Tienes?")
19 fmt.Print(">>> ")
20 fmt.Scanln(&mi_edad)
21 fmt.Println(calcula_edad(mi_edad))
22}
Condicional Switch#
Estructura de un switch:
1package main
2
3import "fmt"
4
5func main() {
6 var operacion string
7
8 fmt.Print("¿Qué quieres saber? \n>>> ")
9 fmt.Scanln(&operacion)
10
11 switch operacion {
12 case "nombre":
13 fmt.Println("Me llamo Guillermo")
14 case "apellidos":
15 fmt.Println("Mis apellidos son Granados Gómez")
16 case "edad":
17 fmt.Println("Tengo 33 años")
18 default:
19 fmt.Println("No reconozco el comando...")
20 }
21}
Atención
Se pueden validar más de un valor en case añadiéndolos con comas: case “a”,”e”,”i”,”o”,”u”
Nota
Los Switch en GO permiten validar condiciones como a > 10 de un modo similar a if.
Bucle for#
for básico:
1package main
2
3import "fmt"
4
5func main() {
6
7 for i := 0; i <= 10; i++ {
8 fmt.Println("Repetición nº", i)
9 }
10}
foreach:
1package main
2
3import "fmt"
4
5func main() {
6 // existe un slice:
7 consolas := []string{"Megadrive", "Playstation", "Gameboy"}
8
9 // y lo podemos recorrer con un for y range:
10 for i, v := range consolas {
11 fmt.Println(i, v)
12 }
13
14 // si no queremos usar el índice:
15 for _, v := range consolas {
16 fmt.Println(v)
17 }
18}
Bucle while#
Según la guía de Go el bucle For es el bucle While de go:
1package main
2
3import "fmt"
4
5func main() {
6 var repetir string
7
8 repeticion := 0
9
10 for {
11 repeticion++
12
13 fmt.Println("Repetición nº", repeticion)
14
15 fmt.Print("¿Repetir otra vez? (s/n): ")
16 fmt.Scan(&repetir)
17
18 if repetir == "n" {
19 break
20 }
21 }
22}
Punteros#
Cuando trabajamos con punteros establecemos un enlace con una variable, de modo que por ejemplo en el caso de las funciones, al enviar parámetros lo que mandamos es una copia, pero gracias a los punteros se puede enviar por parámetros la variable original para modificarla.
1package main
2
3import (
4 "fmt"
5)
6
7// La función recibe un puntero tipo string:
8func cambiar(nombre *string) {
9 *nombre = "Adolfo"
10}
11
12func main() {
13 // se crea una variable con un nombre:
14 nombre := "Pedro"
15 fmt.Println(nombre)
16
17 // se envía el puntero de la variable original para modificar:
18 cambiar(&nombre)
19
20 // al imprimir de nuevo la variable original vemos que el nombre cambió:
21 fmt.Println(nombre)
22
23 // podemos ver la referencia de la memoria donde se asignó el puntero:
24 fmt.Println(&nombre)
25}
Defer#
Defer ejecutará la función seleccionada como la última. Esta sentencia se usa normalmente para cerrar archivos.
Ejemplo con funciones:
1package main
2
3import (
4 "fmt"
5)
6
7// funciones a cargar:
8func funcion1() {
9 fmt.Println("Hola desde función 1")
10}
11
12func funcion2() {
13 fmt.Println("Hola desde función 2")
14}
15
16func funcion3() {
17 fmt.Println("Hola desde función 3")
18}
19
20func funcion4() {
21 fmt.Println("Hola desde función 4")
22}
23
24func main() {
25 // ahora se ejecutarán las funciones con los mensajes:
26 funcion1()
27 defer funcion2()
28 funcion3()
29 funcion4()
30}
Tipos de datos avanzados#
Arrays#
Declaración tradicional:
1package main
2
3import "fmt"
4
5func main() {
6 // dclaración de array con tipo definido:
7 var array [5]int
8 array[2] = 7
9 fmt.Println(array[2])
10
11 // asignar valores al array:
12
13 // asignación directa:
14 array2 := [3]string{"Paco", "Pepe", "Adolfo"}
15 fmt.Println(array2[2])
16
17 // Asignación directa sin establecer longitud:
18 array3 := [...]string{"Galletas", "Fresas", "Aceite", "Tomates"}
19 fmt.Println(array3[2])
20
21 // recuperar una parte del array:
22 fmt.Println(array3[:2])
23}
Array multidimensional:
1package main
2
3import "fmt"
4
5func main(){
6 // declarar array multidimensional:
7 var arrayMulti [4][4]int
8
9 // asignar un valor a una posición:
10 arrayMulti[2][1] = 11
11
12 // utilizar el valor asignado:
13 fmt.Println(arrayMulti[2][1])
14}
Nota
Como en otros lenguajes de programación clásicos los arrays son de un tamaño definido previamente en su declaración. Para trabajar con tamaños dinámicos existen los Slices
Slices#
Declaración tradicional:
1package main
2
3import "fmt"
4
5func main() {
6 // declaración y asignación directa:
7 personas := []string{"Paco", "Pepe", "Adolfo"}
8 fmt.Println(personas[2])
9
10 // declarar y asignar una parte de otro slice:
11 var dos []string = personas[:2]
12
13 fmt.Println(dos)
14}
Slice multidimensional:
1package main
2
3import "fmt"
4
5func main(){
6 // declaración y asignación directa:
7 agenda := [][]string{
8 []string{"Paco", "22", "Futbolista"},
9 []string{"Pedro", "34", "Barrendero"},
10 }
11
12 fmt.Println(agenda[0][0], "es un", agenda[0][2], "y tiene", agenda[0][1], "años")
13}
Mapas#
Los mapas son colecciones de datos de la misma forma que un diccionario en Python o un objeto literal en JavaScript.
1package main
2
3import "fmt"
4
5// se crea un struct:
6type Consola struct {
7 marca, modelo string
8 lanzamiento int
9}
10
11func main() {
12 // ahora se crea el mapa y se utiliza el struct de base:
13 var consolas = map[int]Consola{
14 0: Consola{marca: "Sega", modelo: "Saturn", lanzamiento: 1994},
15 1: Consola{marca: "Sony", modelo: "PlayStation", lanzamiento: 1994},
16 }
17
18 // añadir un nuevo valor con su clave definida:
19 consolas[2] = Consola{marca: "Nintendo", modelo: "64", lanzamiento: 1996}
20
21 fmt.Println(consolas)
22}
Importante
Para crear un mapa vacío lo más común es utilizar la función make()
Control de errores#
El control de errores en GO no funciona del mismo modo que en otros lenguajes de programación. En el caso de GO cuando se realizan ciertas operaciones estas requieren de dos variables, una de ellas la que se esta trabajando y la segunda un error que si todo va bien devuelve un valor nil. Si no devuelve nil usamos una condición if para devolver un mensaje de error:
1package main
2
3import (
4 "fmt"
5 "log"
6 "strconv"
7)
8
9func main() {
10
11 num := "40.36"
12
13 num_entero, err := strconv.Atoi(num)
14
15 // en este caso manejamos el error:
16 if err != nil {
17 log.Fatal(err, "\n El valor introducido no es un entero")
18 }
19
20 fmt.Println(num_entero)
21
22}
Programación modular#
Funciones#
Procedimienos:
1package main
2
3import "fmt"
4
5// declarar una función:
6func saludar() {
7 fmt.Println("Saludo desde función")
8}
9
10func main() {
11 // utilizar una función:
12 saludar()
13}
funciones:
1package main
2
3import "fmt"
4
5// las funciones retornan un valor que se debe definir:
6func saludar() string {
7 return "Saludo desde función"
8}
9
10func main() {
11
12 // utilizar una función:
13 fmt.Println(saludar())
14}
uso de parámetros:
1package main
2
3import "fmt"
4
5// los parametros se reciben con un valor definido::
6func saludar(nombre string) string {
7 saludo := "Hola " + nombre
8 return saludo
9}
10
11func main() {
12
13 // pasar un parámetro:
14 fmt.Println(saludar("Guillermo"))
15}
Recibir parámetros indefinidos:
1package main
2
3import (
4 "fmt"
5)
6
7// enviar parámetros de forma dinámica:
8func imprimir(cosas ...string) {
9 fmt.Println(cosas)
10}
11
12func main() {
13
14 imprimir("Consola", "Movil", "Tablet")
15
16}
Retorno múltiple:
1package main
2
3package main
4
5import "fmt"
6
7// se define entre parentesis el tipo de devolución de varios valores:
8func nombreCompleto(nombre string, apellidos string) (string, string) {
9 // se devuelven dos valores:
10 return nombre, apellidos
11}
12
13func main() {
14 // asignamos los valores a las variables:
15 n, m := nombreCompleto("Guillermo", "Granados Gómez")
16
17 // asignar un elemento con retorno múltiple:
18 soloNombre, _ := nombreCompleto("Guillermo", "Granados Gómez")
19
20 fmt.Println("Me llamo", n, m)
21 fmt.Println("Solo mi nombre es:", soloNombre)
22}
Funciones anónimas:
1package main
2
3import "fmt"
4
5// se crea la función:
6func sumar(a, b int) int {
7 return a + b
8}
9
10func main() {
11 // se crea una variable con las caracteristicas de la función:
12 var operacion func(int, int) int
13
14 // y se asigna la función anterior a la declaración anterior:
15 operacion = sumar
16
17 fmt.Println(operacion(20, 15))
18}
Programación orientada a objetos#
El paradigma orientado a objetos en GO cambia radicalmente frente a otro lenguajes sustituyendo las clases por estructuras.
Structs#
Los Structs son estructuras de datos similares a las clases con la diferencia que estos carecen de constructores y métodos de antemano.
1package main
2
3import "fmt"
4
5// Crear una estructura:
6type Consola struct {
7 marca string
8 modelo string
9 lanzamiento int
10}
11
12func main() {
13 // crear un nuevo objeto del tipo Consola:
14 playstation := Consola{marca: "Sony", modelo: "Playstation", lanzamiento: 1994}
15
16 // uso de atributos:
17 fmt.Println("La consola", playstation.marca, playstation.modelo, "fue lanzada en", playstation.lanzamiento)
18}
Métodos de structs#
1package main
2
3import "fmt"
4
5type Consola struct {
6 marca string
7 modelo string
8 lanzamiento int
9}
10
11// Método de Consola:
12// los métodos reciben primero un puntero a la structura y luego los datos:
13func (c *Consola) imprimir() { // en los paréntesis de imprimir recibe los parámetros requeridos:
14 fmt.Println("La consola", c.marca, c.modelo, "fue lanzada en", c.lanzamiento)
15}
16
17func main() {
18 playstation := Consola{marca: "Sony", modelo: "Playstation", lanzamiento: 1994}
19
20 // ejecutar la función:
21 playstation.imprimir()
22}
Herencia#
uso de clases no instanciables:
1package main
2
3import "fmt"
4
5type Consola struct {
6 marca string
7 modelo string
8 lanzamiento int
9}
10
11func (c *Consola) imprimir() {
12 fmt.Println("La consola", c.marca, c.modelo, "fue lanzada en", c.lanzamiento)
13}
14
15// Herencia:
16type Portatil struct {
17 // cargar el struct del que se quiere heredar:
18 Consola
19 alimentacion string // se pueden añadir nuevos atributos
20}
21
22// también se pueden añadir métodos que utilicen los atributos y métodos del padre:
23func (p *Portatil) imp_portatil() {
24 fmt.Println("La consola", p.marca, p.modelo, "fue lanzada en", p.lanzamiento, "y utiliza", p.alimentacion, "para funcionar")
25}
26
27func main() {
28 playstation := Consola{marca: "Sony", modelo: "Playstation", lanzamiento: 1994}
29
30 playstation.imprimir()
31
32 // crear objeto, aqui solo se puede añadir los atributos existentes en el struct:
33 gameboy := Portatil{alimentacion: "4 Pilas AAA"}
34 // para añadir los atributos del padre se realiza de forma individual:
35 gameboy.marca = "Nintendo"
36 gameboy.modelo = "Gameboy"
37 gameboy.lanzamiento = 1990
38
39 // se puede ver como se aislan los atributos del padre y los del hijo:
40 fmt.Println(gameboy)
41
42 gameboy.imprimir()
43 gameboy.imp_portatil()
44}
Interfaces#
1package main
2
3import "fmt"
4
5// se crea un interface y se le asignan los métodos del struct:
6type Printer interface {
7 imprimir()
8 encender()
9}
10
11type Consola struct {
12 marca string
13 modelo string
14 lanzamiento int
15}
16
17func (c *Consola) imprimir() {
18 fmt.Println("La consola", c.marca, c.modelo, "fue lanzada en", c.lanzamiento)
19}
20
21func (c *Consola) encender() {
22 fmt.Println("Se ha encendido la", c.modelo)
23}
24
25type Portatil struct {
26 consola Consola
27 alimentacion string
28}
29
30// se crean las funciones que manejará los métodos usando el interface:
31func imprimirConsola(printer Printer) {
32 printer.imprimir()
33}
34
35func encenderConsola(printer Printer) {
36 printer.encender()
37}
38
39func main() {
40 playstation := Consola{marca: "Sony", modelo: "Playstation", lanzamiento: 1994}
41 // se utiliza el interface en lugar
42 imprimirConsola(&playstation)
43 encenderConsola(&playstation)
44}
Importar y exportar#
Paquetes en GO#
GO reconoce cada carpeta como un paquete, de este modo en una aplicación básica existirá un archivo main.go referenciando al paquete main y el resto de archivos exportarán sus funciones automáticamente si estan son públicas, que en GO las funciones públicas comienzan en Mayúscula.
Paso 1: Crear nuevo directorio y dentro un archivo main.go
Paso 2: Crear archivo go.mod - Abrir terminal en la raiz del proyecto y ejectuar
go mod init nombre_proyecto
Paso 3: Crear un nuevo paquete consolas y dentro un archivo al que llamaremos listar.go:
1package consolas // cada paquete lleva el nombre de su carpeta correspondiente
2
3import "fmt"
4
5// las funciones solo serán públicas si las ponemos en mayúsculas:
6func Listado() {
7 fmt.Println("NES, Gameboy, Megadrive, Saturn")
8}
Paso 4: Importar paquete y ejecutar función en main.go:
1package consolas // cada paquete lleva el nombre de su carpeta correspondiente
2
3import "fmt"
4
5// las funciones solo serán públicas si las ponemos en mayúsculas:
6func Listado() {
7 fmt.Println("NES, Gameboy, Megadrive, Saturn")
8}
Paso 5: Para ejecutar todo el proyecto ir a raiz desde consola y ejecutar
go run .