Mensaje a navegantes: colabora para que estos contenidos sean gratuitos. Conoces Brave ?

Es un navegador web que permite navegar más rápido, bloquear todos los anuncios y te permite navegar respetando tu privacidad.

Recompensa nuestro contenido que más te guste con tokens BAT que se generan en Brave. Descarga el navegador que te va a cambiar la manera de navegar por Internet.

Varias organizaciones (Colegios, Ministerios, Bancos, Ayuntamientos, Universidades españolas y latino-americanas, instituciones autonómicas) y empresas del sector han utilizado nuestros tutoriales online, a qué esperas tú ?

Gana criptomonedas Stellar XLM o EOS gratis, simplemente viendo unos videos educativos sobre el funcionamiento de estas criptmonedas.
Necesitarás una wallet en Coinbase para conseguir hasta $50
XLM | EOS

Buscar
Cursos akademus

 

alojamiento wordpress

 

alojamiento digital ocean

Deploya tu app en segundos. Consigue $50 de Digital Ocean

Colabora con nosotros

Deja un comentario o comparte el artículo que más te guste o envíanos BAT tokens

Contacta con nosotros para disponer de más información.

El lenguaje Go

 

lenguaje go

 

En este artículo hacemos una introducción al lenguaje Go

El lenguaje Golang de Google también llamado Go. Vamos a ver las características principales y luego haremos un pequeño programa de prueba para ilustrar como funciona.

El lenguaje Go o también llamado Golang fue creado por Google a mediados del año 2009, y hasta entonces no ha parado de incrementar su popularidad, hasta situarse en el Top 10 de los lenguajes de programación más utilizados hoy en día.

Principalmente se creó para la parte del backend, donde era el reino de Java y PHP, y Ruby en menor medida. También lo han vendido como el lenguaje C del siglo XXI.

Características

Es un lenguaje de programación estructurado y compilado. Está disponible para Windows, Mac OS y Linux.

Dispone de un recolector de basura del mismo modo que Java, con lo que no hay que llevar una contabilidad de punteros en memoria.

La sintaxis es parecida a C y contiene algunos parecidos con Python. Aunque la manera de definir el tipo de las variables es precisamente poniendo su tipo al final de la variable. Además permite definir el tipo de varias variables al mismo tiempo. 

Algo interesante es que se pueden devolver más de una variable de retorno de una función.

Esto es sin duda una de las marcas de la casa, la sencillez y facilidad a la hora de programar, facilitando la vida al programador.

En principio tiene la posibilidad de programación orientada a objetos aunque para los que conocen Java, su interpretación es algo especial. De hecho no permite la herencia.

Es un lenguaje de programación compilado. Se genera código nativo para cada plataforma.

A nivel de concurrencia lo borda gracias a las gorutines, haciendo que la programación concurrente sea todo un placer.

Se estructura en paquetes (algo similar a Java), y existe un paquete especial llamado "main" que contiene una función llamada main(), que es el punto de entrada de un programa. Algo parecido al main de Java y C.

Como siempre, es mejor aprender practicando, así que vamos a instalar primero el Golang y vamos a realizar un programa de ejemplo.

 

Instalar Go

Para Windows prodemos descargar el programa de aquí y para Linux podemos hacer un apt-get install golang.

Como editor de código vamos a usar el Microsoft Visual Code, que tiene un plugin muy bueno para Go.

 

Crear el programa

Para empezar creamos una carpeta llamada spider y creamos un fichero main.go dentro de ella.

La estructura inicial del programa será: 

package main

import "fmt"

func main(){
  fmt.Println("Run")
}

Este es el esqueleto básico.  Vemos el uso del paquete por defecto, la importación de fmt, que sirve para leer y escribir por terminal y el uso de la función main.

 Todos los programas go, tienen que tener un punto de entrada y ese es precisamente el método main del package main.

Por cierto, el punto y coma no es necesario en go.

Para compilar el programa hay que escribir go build main.go y nos generará un fichero ejecutable.

Otro comando interesante es gofmt -w main.go, que se encarga de formatear el código y sobreescribirlo (por eso el flag -w).

Y otro más es goimports -w main.go, que se encarga de importar y corregir los paquetes que nos hayamos olvidado.

 

Ejecutar el programa

Para ejecutarlo en el terminal también se puede escribir go run main.go y nos sacará por pantalla Run. Así de simple. Es un modo fácil de testear los programas sin tener que compilarlos.

Tipos de datos

Como lo mayoría de lenguajes, en Go podemos encontrar cadenas de texto (string), enteros (int), números con coma (float), booleanos (true/false) y el tipo "null" que aquí es "nil".

Para definir variables se utiliza var. El propio compilador ya infiere el tipo de dato que es. Si queremos definir e inicializar una variable podemos usar :=

Las constantes se definen con const como en otros lenguajes.

Aunque el tipo de dato lo infiere, habitualmente se especifica el tipo de datos después de la variable.

Arrays

Podemos definir listas de elementos de una cierta longitud. Tenemos la función len para obtener el tamaño del array.

Un tipo parecido al array es el slice que permite ampliar el tamaño con la función append. Por supuesto también tiene la función len. Adicionalmente se puede copiar un slice en otro con la función copy y se pueden obtener slices de slices especificando la posición inicial y la final. Esto es parecido a Python

Los arrays se pueden ordenar con la función sort importando el paquete "sort".

Maps

Los maps son otro tipo de datos conocidos en Python como dict, o hashes en Ruby. Se crean con la palabra make(map[tipo llave]tipo valor). Tenemos la función len para obtener el número de pares llave/valor. También la función delete(mapa, "llave") elimina un par llave/valor del map.

Range

Esta sentencia sirve para iterar los elementos de ciertas estructuras, como los slices y arrays, o los maps o incluso cadenas de texto (string).

Bucles

Usa el for para iterar. No se utilizan paréntesis, sólo los corchetes. Y tenemos el break y el continue como otros lenguajes.

Funciones

Las funciones se definen con func y al igual que las variables se especifica el tipo de datos que devuelve. Algo curioso como Python es que puede devolver más de un valor, y es habitual devolver un dato, y un tipo de dato de error.

Las funciones pueden recibir varios parámetros no especificados determinados con ... y se pueden invocar pasando un slice de este modo mifun(params...)

Punteros

Una característica de Go es que permite usar punteros. Así si una función se define como func mifun(puntero *int) especifica que recibe un puntero a int.

Para obtener la dirección de memoria del puntero se especifica &puntero

Structs

Otro tipo de dato copiado del C. Los struct definen tipos de datos que contienen campos de diferentes tipos de datos.

type coche struct {
  marca string
  modelo string
  km int
}

Se crea un struct con c:= coche{"Seat", "Arona", 24000}

Como suele ser habitual se accede a los campos con el punto . y se obtiene el puntero a la estructura de datos con el &

Errores

Los errores se definen con errors.New("mi error") importando el paquete "errors".

Habitualmente se compara el error con nil para evaluar que no hay errores en el retorno de una función.

Panic

Un tipo de error especial es el Panic. Es para errores inesperados, valores inesperados, muestra las trazasd de error y aborta el programa.

Defer

Para gestionar el cierre de recursos se usa defer por ejemplo para cerrar ficheros abiertos o conexiones de red.

Json/Xml/Base64

Go incorpora por defectos varios paquetes para codificar y descodificar JSON y XML y Base64.

Fechas

Go también incorpora paquetes para gestionar fechas y tiempos

Ficheros

Go permite trabajar con ficheros como los lenguajes habituales.

HTTP

Go incorpora paquetes para trabajar con http ya sea como cliente o como servidor.

Procesos

Asimismo Go incluye paquetes para ejecutar procesos y gestionar señales de tipo UNIX

Sentencias de flujo

Usa el if y el else. Lo mismo que el for, las condiciones sin paréntesis y las sentencias del if y el else van entre corchetes.

También usa switch para sentencias de flujo de varias opciones.

Goroutines

Es la manera de ejecutar código concurrente en un programa go, algo parecido a los threads de Java por ejemplo. Se definen con la sentencia go mifun(), aunque también se puedem usar con una función anónima.

Para comunicar las goroutines se usan los canales. Se pueden enviar valores a través de los canales de una goroutine a otra. Para crear un canal se especifica mican := make(chan string).

Para enviar un valor al canal se usa mican <- "cadena de texto" y para recibirlo se usa valorecibido := <-mican

Se pueden usar canales con un tipo de dato booleano para sincronizar goroutines. Asimismo se puede usar la sentencia select para esperar en múltiples canales.

Ejemplo práctico

Vamos a crear un programa para que se descargue una página de internet.

Para ello el programa tendrá que pedir por la consola la dirección (url) y luego accederá a la URL e imprimirá el contenido.

Para la entrada de parámetros usaremos el paquete "flag" .

 

func main(){

weburl:=flag.String("url","google.com","La URL a buscar")
         flag.Parse()

         fmt.Println("Run:")
         fmt.Println(*weburl)
}

 A continuación con la ayuda del paquete net invocaremos a la url y con el paquete ioutils dispondremos de métodos para lectura y escritura.

También podemos usar el paquete os para salir del programa en caso de error.

Así pues el ejemplo quedaría de la siguiente manera: 

 

package main

import ("fmt"
    "flag"
    "net/http"
    "io/ioutil"
    "os")

func main(){

weburl:=flag.String("url","http://google.com","La URL a buscar")
         flag.Parse()

         fmt.Println("Run:")
         fmt.Println(*weburl)
         resp, err := http.Get(*weburl)  
         if err != nil {
           fmt.Println("Error http:", err)
             os.Exit(1)
         }

       body, err := ioutil.ReadAll(resp.Body)  
         if err != nil {                                      
           fmt.Println("Error lectura:", err)
             os.Exit(1)
         } 

       fmt.Println(string(body))   
}

Repasemos lo más importante del lenguaje Go:

Las sentencias if-else no requieren paréntesis, pero sí las llaves de apertura y cierre.

También se puede ver que para asignar una variable, se puede usar el ":=". Este es un modo fácil de asignar el valor y el tipo a la variable. 

En Go existen los tipos habituales: int, bool, string, []int, etc. Si no asignamos un valor a la variable, Go lo pondrá a 0,  "",  0.0, false, nil.

Por otro lado, se puede asignar una variable del modo más habitual, definiendo su tipo, con la sentencia var. Así var cadena string = "cadena"

Los arrays se definen como var lista [10]string y se pueden informar los valores como es habitual: lista[0] = "Hola"

Podemos definir lo que llaman slices, que son arrays sin un tamaño fijado, que pueden crecer dinámicamente: var lonchas []string

Para ello se utiliza la sentencia append(lonchas, "cadena"), que añade elementos al array. O de un modo más compacto: lonchas []string{"uno","dos"}

Luego para recorrer los elementos de un slice se puede hacer con un bucle:

for i,elem := range lonchas { ... }

Consejo: Mira la documentación oficial para conocer más sobre range y la variable no usada "_".

 

Otro modo de leer los parámetros de entrada es con os.Args. Esto es un array de elementos, donde el [0] es el nombre del ejecutable, el [1] el primer parámetro, y así sucesivamente. Para leer la longitud de un array se puede usar la función len(variable).

 Si queremos compilar el programa escribiremos go build spider.go y se generará un ejecutable.

 

 Definir estructuras

Un modo de enriquecer los tipos de datos es con el uso de estructuras.

Se definen fuera de la función main, y se inicializan dentro de la función main, del estilo:

type coche struct {
     marca string
     modelo string
    puertas int
}

Luego se inicilizaría tal como micoche := coche{marca: "seat", modelo: "ibiza", puertas: 3}

Estas estructuras también pueden tener métodos, por ejemplo el color del coche y se definen con la sentencia:

func (c coche) color() string { ... }

Dentro del método se podría acceder a las propiedades de la estructura con el punto como c.marca o c.modelo.

Esto sería lo más parecido a orientación a objetos que Go puede tener. Exsite además la sentencia interface que permite definir métodos comunes que deben implementar las diferentes estructuras.

 Nota: Para que una función se pueda usar fuera de su paquete hay que adoptar una convención de poner la primera letra en mayúsculas.

 

El puntero contrataca

Sí, de nuevo volvemos a tener punteros en Go. Es decir.

Si se define una variable cadena := "hola" y otra cadena2 := cadena. La segunda obtiene una copia del valor de la primera.

Si definimos cadena2 := &cadena   entonces la segunda obtiene una referencia al valor de la primera.

 Los métodos pueden tener punteros como parámetros, para definirlo así se usa el * antes del tipo de estructura.

 

Definir funciones

Para definir funciones, se utiliza la sintaxis:

func nombre (variable tipo) tiporetorno { ... }

Un modo curioso de implementar que una función puede devolver un error, es retornando dos variables, sí eso mismo, dos variables al mismo tiempo.

func nombre (variable tipo) (tiporetorno, error) { ... }

Para ello hay que importar el paquete errors y asignar un error tal como: 

err := errors.New("Error a")

Si queremos devolver el resultado de una función sin error, lo podemos poner a nil. De ese modo

return variableretorno, nil

Por el contrario si encontramos un error, es algo común comprobarlo, entonces logamos el mensaje y salimos del programa:

if err != nil {
     fmt.Println(err)
       os.Exit(1)
}

Un tipo especial de funciones son las gorutines, que son funciones que se ejecutan concurrentemente con el resto. Y para ello se definen con la sentencia go delante de la función.

 

Bucles

Realmente sólo vamos a usar la sentencia for, ya que no dispone de ninguna otra. Pero vamos a ver que realmente es como una navaja suiza. Nos va a permitir realizar todo tipo de bucles. Como cabía esperar, no utiliza los paréntesis, pero las llaves son obligatorias.

for expr antes 1a iterac ; condicion antes cada interac ; expr después de iterac { ... }

Por ejemplo para iterar de 0 a 9: for i := 0 ; i<10 otro="" uso="" en="" la="" forma:="" p="">

for condicion  { ... } 

sin especificar dentro del for la variable antes de la 1a iterac.

Para salir del bucle, se usa la sentencia break, como en muchos otros lenguajes de programación.

La sentencia

for { .. }

haría un bucle infinito, que se ejecutaría hasta que el programa se abortara.