LinuxParty

Inicio desactivadoInicio desactivadoInicio desactivadoInicio desactivadoInicio desactivado
 

Programar en Go.

Tal vez has oído hablar de Go. Se introdujo por primera vez en 2009, pero como cualquier nuevo lenguaje de programación, tardó un tiempo en madurar y estabilizarse hasta el punto en que se volvió útil para aplicaciones de producción. Hoy en día, Go es un lenguaje bien establecido que se utiliza para la programación de redes y bases de datos, el desarrollo web y la escritura de herramientas DevOps. Fue utilizado para escribir Docker, Kubernetes, Terraform y Ethereum. Go se está acelerando en popularidad, con una adopción que aumenta en un 76% en 2017, y ahora hay grupos de usuarios de Go y conferencias de Go. Si desea agregar a sus habilidades profesionales, o simplemente está interesado en aprender un nuevo lenguaje de programación, es posible que desee verificarlo.

¿Por qué Go?

Go fue creado en Google por un equipo de tres programadores: Robert Griesemer, Rob Pike y Ken Thompson. El equipo decidió crear Go porque estaban frustrados con C++ y Java, que a lo largo de los años se había vuelto incómodo y torpe para trabajar. Querían devolver la diversión y la productividad a la programación.

Los tres tienen logros impresionantes. Griesemer trabajó en el motor de JavaScript V8 ultrarrápido de Google, utilizado en el navegador web Chrome, en el entorno de ejecución de JavaScript Node.js y en otros lugares. Pike y Thompson formaron parte del equipo original de Bell Labs que creó Unix, el lenguaje C y las utilidades de Unix, lo que llevó al desarrollo de las utilidades GNU y Linux. Thompson escribió la primera versión de Unix y creó el lenguaje de programación B, en el que se basó C. Más tarde, Thompson y Pike trabajaron en el equipo del sistema operativo Plan 9, y también trabajaron juntos para definir la codificación de caracteres UTF-8.

Go tiene la seguridad de la escritura estática y la recolección de basura junto con la velocidad de un lenguaje compilado. Con otros idiomas, "compilado" y "recolección de basura" se asocian con esperar a que el compilador finalice y luego obtener programas que se ejecutan lentamente. Pero Go tiene un compilador muy rápido que hace que los tiempos de compilación sean apenas perceptibles, y un recolector de basura moderno y ultra eficiente. Obtienes tiempos de compilación rápidos junto con programas rápidos. Go tiene una sintaxis y una gramática concisas con pocas palabras clave, lo que le da a Go la simplicidad y la diversión de lenguajes interpretados de tipo dinámico como Python, Ruby y JavaScript.

Si sabe que C, C ++, Java, Python, JavaScript o un lenguaje similar, muchas partes de Go, incluidos los identificadores, los operadores y las declaraciones de control de flujo, le resultarán familiares. Un ejemplo simple es que los comentarios se pueden incluir como en ANSI C:

 // Este comentario continúa hasta el final de la línea.

 /* Este tipo
    de comentario
    puede abarcar
    lineas multiples  * /

En otras formas, Go es muy diferente de C. Una diferencia obvia es su sintaxis de declaración, que es más parecida a la de Pascal y Modula-2. Aquí es cómo se declara una variable entera en Go:

 var i int

Esta sintaxis puede parecer "hacia atrás" a un programador en C o Java, pero es mucho más natural y más fácil de trabajar. Las declaraciones en Go generalmente se pueden traducir directamente al inglés o a otro idioma humano. En el ejemplo anterior, la declaración se puede leer como "La variable i es un número entero". Aquí hay algunos ejemplos más simples:

 var x float32 // "La variable x es un número de punto flotante de 32 bits".
 var c byte // "Variable c es un byte".
 var s string // "Variable s es una cadena".

Y también es posible hacer esto con tipos de datos más complejos:

var a [32]int	 // "La variable a es una matriz de 32 enteros".

 var s struct {   // "Variable s es una estructura compuesta de
	 i int // i, un entero,
	 b byte // b, un byte,
	 s [] int // y s, una porción de enteros ".
 }

La idea del diseño de Go es tener las mejores partes de muchos idiomas. Al principio, Go se parece mucho a un híbrido de C y Pascal (ambos son sucesores de Algol 60), pero al mirar más de cerca, también encontrarás ideas tomadas de muchos otros idiomas.

Go está diseñado para ser un lenguaje compilado simple que es fácil de usar, a la vez que permite programas escritos de forma concisa que se ejecutan de manera eficiente. Go carece de características extrañas, por lo que es fácil de programar con fluidez, sin necesidad de consultar la documentación del idioma durante la programación. Programar en Go es rápido, divertido y productivo.

Vamonos

Primero, asegúrate de tener instalado Go. El Go Team tiene distribuciones instaladas fácilmente para Linux (incluyendo Raspberry Pi), macOS, FreeBSD y el sitio web de Windows on the Go en https://golang.org/dl/

También deberá asegurarse de que su variable de entorno PATH esté configurada correctamente para permitir que su shell o procesador de línea de comandos encuentre los programas que conforman el sistema Go. En Linux, macOS o FreeBSD, agregue / usr / local / go / bin a su PATH , algo como esto:

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

En Windows, configurar una variable de entorno PATH es un poco más complicado. En cualquier caso, puede encontrar instrucciones para configurar PATH en las instrucciones de instalación de su sistema, que aparecen en una página web después de hacer clic para descargar el paquete de instalación.

En Linux, puede instalar Go utilizando el sistema de administración de paquetes de su distribución. Para encontrar el paquete Go, intente buscar "golang", que es un sinónimo de Go. Incluso si puede hacerlo, puede ser mejor descargar una distribución desde el sitio web de Go para asegurarse de obtener la versión más reciente.

Cuando tengas instalado Go, prueba este comando:

$ go version
go version go1.11.1 linux/amd64

La salida muestra que tengo la versión 1.11.1 de Go instalada en mi máquina Linux de 64 bits.

Con suerte, ya te has interesado y quieres ver cómo se ve un programa Go completo. Aquí hay un programa muy simple en Go que imprime "hola mundo".

package main

import "fmt"

 func main() {
     fmt.Printf ("hola, mundo \n")
 }

Juega con este código en el Go Playground

La línea principal del paquete define el paquete del que forma parte este archivo. Nombrar main como el nombre del paquete y la función le dice a Go que aquí es donde debe comenzar la ejecución del programa. Necesitamos definir un paquete principal y una función principal incluso cuando solo hay un paquete con una función en todo el programa.

En el nivel superior, el código fuente de Go está organizado en paquetes. Cada archivo fuente es parte de un paquete. Importar paquetes y exportar funciones es un juego de niños.

La siguiente línea, importar "fmt" , importa el paquete fmt . Es parte de la biblioteca estándar de Go y contiene la función Printf () . A menudo necesitará importar más de un paquete. Para importar los paquetes fmt , os y strings , puede escribir

import "fmt"
import "os"
import "strings"

o

import (
    "fmt"
    "os"
    "strings"
    )

Usando paréntesis, la importación se aplica a todo lo que aparece dentro de los paréntesis, guardando algo de escritura. Verá que los paréntesis se usan de esta manera nuevamente en otras partes de Go, y Go también tiene otros tipos de atajos de teclado.

Los paquetes pueden exportar constantes, tipos, variables y funciones. Para exportar algo, solo escribe con mayúscula el nombre de la constante, tipo, variable o función que quieres exportar. Es así de simple.

Observe que no hay punto y coma en el programa "Hola, mundo". Los puntos y comas en los extremos de las líneas son opcionales. Aunque esto es conveniente, conduce a algo que debe tener cuidado cuando se aprende Go por primera vez. Esta parte de la sintaxis de Go se implementa utilizando un método tomado del lenguaje BCPL. El compilador usa un conjunto simple de reglas para "adivinar" cuando debería haber un punto y coma al final de la línea, e inserta uno automáticamente. En este caso, si el paréntesis derecho en main () estuviera al final de la línea, activaría la regla, por lo que es necesario colocar el corchete abierto después de main () en la misma línea.

Este formato es una práctica común que se permite en otros idiomas, pero en Go, es obligatorio. Si colocamos el soporte abierto en la siguiente línea, obtendremos un mensaje de error.

Ir es inusual ya que requiere o favorece un estilo específico de formato de espacio en blanco. En lugar de permitir todo tipo de estilos de formato, el lenguaje viene con un estilo de formato único como parte de su diseño. El programador tiene mucha libertad para violarlo, pero solo hasta cierto punto. ¡Esto es una camisa de fuerza o una bendición, según tus preferencias! El formateo de forma libre, permitido por muchos otros idiomas, puede llevar a una mini Torre de Babel, lo que hace que otros programadores no puedan leer el código. Go evita que al hacer que un estilo de formato único sea el preferido. Ya que es bastante fácil adoptar un estilo de formato estándar y acostumbrarse a usarlo habitualmente, eso es todo lo que tiene que hacer para escribir un código de lectura universal. ¿Lo suficientemente justo? Go incluso viene con una herramienta para reformatear tu código para que se ajuste al estándar:

$ go fmt hello.go

Solo dos advertencias: su código debe estar libre de errores de sintaxis para que funcione, por lo que no solucionará problemas, como no poner una llave abierta en la misma línea. Además, sobrescribe el archivo original, por lo que si desea conservar el original, haga una copia de seguridad antes de ejecutar go fmt .

La función main () tiene solo una línea de código para imprimir el mensaje. En este ejemplo, la función Printf () del paquete fmt se usó para hacerla similar a escribir un programa "hola, mundo" en C. Si lo prefiere, también puede usar

fmt.Println("hello, world")

para guardar escribiendo el \ n carácter de nueva línea al final de la cadena. Este es otro ejemplo de que Go es similar a C y Pascal. Obtiene funciones de impresión y escaneo formateadas que se asemejan mucho a las que están acostumbrados a los programadores C, además de funciones simples y convenientes como Println () que son similares a writeln () y otras funciones en Pascal.

Así que vamos a compilar y ejecutar el programa. Primero, copie el código fuente de "hola, mundo" a un archivo llamado hello.go . Luego compílalo usando este comando:

$ go build hello.go

Y para ejecutarlo, use el ejecutable resultante, llamado hola , como un comando:

 $ hello
 Hola Mundo

Como método abreviado, puede realizar ambos pasos en un solo comando:

$ go run hello.go
hello, world

Eso compilará y ejecutará el programa sin crear un archivo ejecutable. Es genial para cuando está desarrollando un proyecto activamente y solo está buscando errores antes de realizar más ediciones.

A continuación, veamos algunas de las características principales de Go.

Concurrencia

El soporte integrado de Go para la concurrencia, en forma de goroutines , es una de las mejores características del lenguaje. Un goroutine es como un proceso o hilo, pero es mucho más ligero. Es normal que un programa Go tenga miles (o incluso unos pocos millones) de goroutines activos. Poner en marcha un goroutine es tan simple como

go f()

La función f () se ejecutará simultáneamente con el programa principal y otros goroutines. Go tiene un medio para permitir que las partes concurrentes del programa se sincronicen y se comuniquen mediante canales . Un canal es algo así como una tubería de Unix; Se puede escribir en un extremo y leer desde el otro. Un uso común de los canales es que los goroutines indiquen cuándo han terminado.

Los goroutines y sus recursos son gestionados automáticamente por el sistema Go Runtime. Con el soporte de moneda de Go, es fácil hacer que todos los núcleos y subprocesos de una CPU de varios núcleos funcionen de manera eficiente.

Sincronización con canales

Cualquier lenguaje que admita procesos de subprocesos múltiples o simultáneos debe tener un mecanismo que permita que el código que se ejecuta simultáneamente o simultáneamente coordine la modificación y el acceso a los datos. Para este propósito, Go tiene canales , que son colas de primero en entrar, primero en salir (FIFO) que funcionan de una manera que les permite ser utilizados para sincronizar goroutines.

En el caso más simple, un canal no tiene buffer y permite solo una operación pendiente a la vez. Por lo tanto, está vacío o tiene una lectura o escritura que está esperando a que otra goroutine realice la acción correspondiente.

La sincronización se realiza como en este ejemplo: Supongamos que un goroutine intenta recibir (leer) de un canal vacío. El sistema de tiempo de ejecución Go pone a la goroutina en reposo hasta que otra goroutina envía (escribe al) canal. Luego hay algo allí para que la primera goroutine reciba, por lo que se despierta y la operación de recepción se realiza correctamente. Este mecanismo permite que se use un canal para hacer que un goroutine espere a que otro lo señale realizando una operación en su canal compartido. Los canales de Go se pueden usar para implementar bloqueos mutuamente exclusivos (mutexes) que se encuentran en otros idiomas, y el paquete de sincronización de Go hace exactamente eso.

Usar canales es muy simple y conciso. Antes de que se utilicen, los canales se asignan mediante la función integrada make () de Go. Por ejemplo,

var intch chan int	// intch es un canal de enteros
intch = make(chan int)	// asigna un nuevo canal de enteros

declara y luego crea un nuevo canal llamado intch para enviar y recibir números enteros. Enviar en un canal es tan simple como

intch <- 1	// envía el entero 1 en el canal

y recibir desde un canal (en otro goroutine) es igual de simple:

var num int	// num es un entero
num = <-intchan	// recibe un número entero del canal

Aquí hay un ejemplo completo que muestra un canal en uso:

 package main

import "fmt"

var intch chan int		// intch is a channel of integers

func main() {
	intch = make(chan int)	// allocate a channel of integers
	go print_number()	// start the goroutine
	intch <- 37		// send 37 on the channel
	<- intch		// wait for a response before exiting
}

func print_number() {
	var number int		// number is an integer

	number = <-intch	// receive an integer from the channel
	fmt.Printf("The number is %d\n",number)  // print it
	intch <- 0		// send a response
}

Juega con este código en el Go Playground

Tipos, métodos e interfaces

Podría preguntarse por qué los tipos y métodos están juntos en el mismo encabezado. Es porque Go tiene un modelo de programación orientado a objetos simplificado que funciona junto con su sistema de tipo expresivo y liviano. Evita por completo las clases y las jerarquías de tipos, por lo que es posible hacer cosas complicadas con tipos de datos sin crear un desastre. En Go, los métodos se adjuntan a tipos definidos por el usuario, no a clases, objetos u otras estructuras de datos. Aquí hay un ejemplo simple:

package main

import "fmt"

// make a new type MyInt that is an integer

type MyInt int

// attach a method to MyInt to square a number

func (n MyInt) sqr() MyInt {
    return n*n
}

func main() {
	// make a new MyInt-type variable
	// called "number" and set it to 5

	var number MyInt = 5

	// and now the sqr() method can be used

	var square = number.sqr()

	// the value of square is now 25

	fmt.Printf("The square of %d is %d\n",number,square)
}

Juega con este código en el Go Playground

Junto con esto, Go tiene una instalación llamada interfaces que permite la mezcla de tipos. Las operaciones se pueden realizar en tipos mixtos siempre y cuando cada uno tenga el método o métodos adjuntos, especificados en la definición de la interfaz, que son necesarios para las operaciones.

Supongamos que hemos creado tipos llamados gato , perro y ave , y cada uno tiene un método llamado age () que devuelve la edad del animal. Si queremos agregar las edades de todos los animales en una sola operación, podemos definir una interfaz como esta:

type animal interface {
    age() int
}

La interfaz de los animales se puede usar como un tipo, lo que permite que los tipos de gato , perro y ave se manejen de manera colectiva al calcular las edades.

Soporte Unicode

Teniendo en cuenta que Ken Thompson y Rob Pike definieron la codificación Unicode UTF-8 que ahora es dominante en todo el mundo, puede que no le sorprenda que Go tenga un buen soporte para UTF-8. Si nunca ha usado Unicode y no quiere molestarse con él, no se preocupe; UTF-8 es un superconjunto de ASCII. Eso significa que puedes continuar programando en ASCII e ignorar el soporte de Go's Unicode y todo funcionará bien.

En realidad, todo el código fuente es tratado como UTF-8 por el compilador y las herramientas Go. Si su sistema está configurado correctamente para permitirle ingresar y mostrar caracteres UTF-8, puede usarlos en los nombres de archivo fuente de Go, los argumentos de la línea de comando y en el código fuente de Go para cadenas literales y nombres de variables, funciones, tipos , y constantes.

Justo debajo, puede ver un programa "hola, mundo" en portugués, que podría estar escrito por un programador brasileño.

package main

import "fmt"

func faça_uma_ação_em_português() {
	fmt.Printf("Olá mundo!\n")
}

func main() {
	faça_uma_ação_em_português()
}

Juega con este código en el Go Playground

Además de apoyar a Unicode de estas maneras, Go tiene tres paquetes en su biblioteca estándar para manejar problemas más complicados relacionados con Unicode.

Resumiendo

A estas alturas, quizás entiendas por qué los programadores de Go están entusiasmados con el lenguaje. Go no tiene solo muchas características buenas, sino que todas están incluidas en un lenguaje diseñado para evitar el exceso de complicaciones. Es un muy buen ejemplo de que todo es mayor que la suma de sus partes.

Para obtener más información sobre Go, visite el sitio web de Go y realice un recorrido por Go .

 

Pin It

Escribir un comentario


Código de seguridad
Refescar



Redes:



 

Suscribete / Newsletter

Suscribete a nuestras Newsletter y periódicamente recibirás un resumen de las noticias publicadas.

Donar a LinuxParty

Probablemente te niegues, pero.. ¿Podrías ayudarnos con una donación?


Tutorial de Linux

Nos obligan a moslestarte con la obviedad de que este sitio utiliza Cookies. Ver política