Probando el Go de Google

Pues leyendo la linux_magazine de este mes (donde me también di por primera vez con scratch) me encontré con un articulo sobre el lenguaje Go_de_Google y me entraron ganas de probarlo, la experiencia es bastante curiosa.

En cuanto a la instalación, usar el binario del proyecto no es especialmente difícil para lo que podría ser, lo bajas del repo, y lanzas un script que lo compila, aquí_están_las_instrucciones. Pero si piensas usar el frontend_de gcc (no veo para que) te auguro un par de dolores de cabeza...

Con este lenguaje de programación, el obligado "hola mundo" quedaría así:

===============================================================================

package main

import "fmt"

func main(){     fmt.Println("Hola, mundo!") }

===============================================================================

Antes ejecutarlo hay que compilarlo y enlazarlo (para 386, 8g ; 8l ).

De primeras se puede ver que los archivos se clasifican en paquetes (para facilitar la importación, supongo), que en vez de #incluir cosas, se importan como lo haría python (siempre y cuando sea solo un módulo, después veremos como hacer con varios), y que no hace falta poner ';' cuando se presuponen (si se sigue el estilo de programación de Go ).

El hola mundo ocupa un mega (frente a los 7 Kb de C), lanzar un "strip -s" no ayuda, hace que su tamaño aumente 200Kb más y provoca que dé un fallo de segmentación ¿?.

Como prueba para ver como es un programa algo más grande, aquí hay un código que descarga un archivo de un servidor FTP [ftp.go], el uso es:

===============================================================================

Uso: ./8.out [[:]@][:]/

===============================================================================

Lo de 8.out es el nombre que le da por defecto el enlazador de Go.

Pero me estoy desviando del tema... esto es lo más destacable con lo que me encotré:

Para importar varias cosas, se hace

===============================================================================

import(     "fmt" / Entrada / Salida /     "net" / Sockets /     "os" / Archivos, errores ... /     "strings" / Manejo de strings /     "strconv" / Conversiones de strings / )

===============================================================================

Que es ciertamente más claro que un bloque de #includes en C.

La cabecera de las funciones recuerda ligeramente a Pascal, empezando la línea con "func", después el nombre de la funcion, los argumentos (variable y tipo en el mismo orden que pascal y inverso a C), y después el tipo que se devolverá , si hay alguno (pueden ser varios)

===============================================================================

func readline (sock *net.TCPConn) (s string){

===============================================================================

Llama la atención que se pueda predefinir una variable a devolver, que no se tendrá que especificar en el return (aquí sería "s")

Otra cosa curiosa tiene que ver con la declaración de variables y su asignación, las variables se pueden declarar a la vez que se crean, sin necesidad de especificar su tipo, esto se hace con el operador := (que también recuerda a la asignación de Pascal), pero al definir el valor de una variable ya declarada se usaría = (el símbolo de asignación de C)

===============================================================================

line := "" for {     line = readline(sock)

===============================================================================

Ya que no lo encontré mencionado en ninguna parte aviso, si una funcion devuelve varias variables y no quieres recojer una, subtituye lo que habría en esa posición por un "_"

===============================================================================

_, e := sock.Read(readData)

===============================================================================

El while ya no existe, su lugar lo toma for ¡!.

En las funciones predefinidas, la primera letra es mayúscula, esto es porque lo que comienza por mayúsculas es exportado por defecto.

===============================================================================

fmt.Println("Hecho")

===============================================================================

El puesto del NULL de C lo ocupa el nil de Pascal.

===============================================================================

if (e != nil){

===============================================================================

La lectura de un Stream (un chan en Go), es muy sencilla

===============================================================================

<-quit

===============================================================================

La escritura también, por supuesto

===============================================================================

quit <- 1

===============================================================================

La concurrecia sigue el mismo camíno, solo hay que añadir "go" antes de la función que sera ejecutada en paralelo

===============================================================================

go download_file(sock, filepath, naddr, quit)

===============================================================================

Y no se me ocurre nada más. En resumen, aunque al principio el lenguaje pareciera que tenía caprichos de diseño y que algunas cosas se hicieron como se hicieron por hacerlo diferente, al final todo encaja dando lugar a un lenguaje fácil de leer y de programar en cuanto se comprende.

No puedo acabar esto sin decir que me temo que al menos hasta hace poco, Go no era del todo estable como lenguaje, me encontré con cosas escritas no hace mucho (unos meses) que ya no compilaban por cambios en el lenguaje.

Nos vemos. [Referencias] http://golang.org/ http://golang.org/doc/effective_go.html http://swehack.se/0417/goroutines-och-tcp-programmering-i-golang https://groups.google.com/group/golang-nuts/

untagged

Probando scratch » « Clon de LOIC en python