![]() | |
Paradigma | Multi-paradigma : concurrente, funcional, imperativo, orientado a objetos |
---|---|
Diseñada por | Robert Griesemer Rob Pike Ken Thompson |
Desarrollador | Los autores de Go |
Apareció por primera vez | 10 de noviembre de 2009 ; Hace 11 años ( 2009-11-10) |
Lanzamiento estable | 1.17.1 ![]() |
Disciplina de mecanografía | Inferido, estático, fuerte, estructural, nominal |
Lenguaje de implementación | Ir, lenguaje ensamblador (gc); C ++ (gofrontend) |
SO | DragonFly BSD, FreeBSD, Linux, macOS, NetBSD, OpenBSD, Plan 9, Solaris, Windows |
Licencia | BSD de 3 cláusulas + concesión de patente |
Extensiones de nombre de archivo | .ir |
Sitio web | golang.org |
Implementaciones importantes | |
gc, gofrontend | |
Influenciado por | |
C, Oberon-2, Limbo, Active Oberon, comunicación de procesos secuenciales, Pascal, Oberon, Smalltalk, Newsqueak, Modula-2, Alef, APL, BCPL, Modula, occam, Erlang, | |
Influenciado | |
Odin, Cristal, Zig |
Go es un lenguaje de programación compilado y tipado estáticamente diseñado en Google por Robert Griesemer, Rob Pike y Ken Thompson. Go es sintácticamente similar a C, pero con seguridad de memoria, recolección de basura, tipificación estructural y simultaneidad de estilo CSP. El idioma a menudo se conoce como Golang debido a su nombre de dominio, pero el nombre correcto es Go. golang.org
Hay dos implementaciones principales:
Un compilador de fuente a fuente de terceros, GopherJS, compila Go to JavaScript para el desarrollo web front-end.
Go fue diseñado en Google en 2007 para mejorar la productividad de la programación en una era de máquinas multinúcleo, en red y grandes bases de código. Los diseñadores querían abordar las críticas de otros lenguajes en uso en Google, pero mantienen sus características útiles:
Los diseñadores estaban motivados principalmente por su aversión compartida por C ++.
Go se anunció públicamente en noviembre de 2009 y la versión 1.0 se lanzó en marzo de 2012. Go se utiliza ampliamente en la producción en Google y en muchas otras organizaciones y proyectos de código abierto.
En noviembre de 2016, los diseñadores tipográficos Charles Bigelow y Kris Holmes lanzaron las fuentes Go y Go Mono específicamente para el proyecto Go. Go es un sans-serif humanista que se parece a Lucida Grande y Go Mono es monoespaciado. Cada una de las fuentes se adhiere al conjunto de caracteres WGL4 y fue diseñada para ser legible con una altura x grande y formas de letras distintas. Tanto Go como Go Mono se adhieren al estándar DIN 1450 al tener un cero cortado, minúsculas l
con cola y mayúsculas I
con serifas.
En abril de 2018, el logotipo original fue reemplazado por un GO estilizado inclinado hacia la derecha con líneas de corriente al final. Sin embargo, la mascota Gopher siguió siendo la misma.
En agosto de 2018, los principales colaboradores de Go publicaron dos "borradores de diseño" para funciones del lenguaje "Go 2" nuevas e incompatibles, genéricos y manejo de errores, y pidieron a los usuarios de Go que enviaran comentarios sobre ellos. La falta de soporte para la programación genérica y la verbosidad del manejo de errores en Go 1.x habían generado críticas considerables.
Go 1 garantiza la compatibilidad para la especificación del idioma y las principales partes de la biblioteca estándar. Todas las versiones hasta la versión actual de Go 1.17 han mantenido esta promesa.
Cada versión principal de Go es compatible hasta que haya dos versiones principales más recientes.
Versión principal | Fecha de lanzamiento inicial | Cambios de idioma | Otros cambios |
---|---|---|---|
1–1.0.3 | 2012-03-28 | Versión inicial | |
1.1–1.1.2 | 2013-05-13 |
|
|
1.2–1.2.2 | 2013-12-01 |
|
|
1.3–1.3.3 | 2014-06-18 | No hay cambios de idioma en esta versión. |
|
1.4–1.4.3 | 2014-12-10 |
|
|
1.5–1.5.4 | 2015-08-19 | Debido a un descuido, la regla que permitía eliminar el tipo de elemento de los literales de sector no se aplicó a las claves de mapa. Esto se ha corregido en Go 1.5. |
|
1.6–1.6.4 | 2016-02-17 | No hay cambios de idioma en esta versión. |
|
1.7–1.7.6 | 2016-08-15 | Aclaración sobre las declaraciones de terminación en la especificación del lenguaje. Esto no cambia el comportamiento existente. |
|
1.8–1.8.7 | 2017-02-16 | Al convertir explícitamente un valor de un tipo de estructura a otro, a partir de Go 1.8 las etiquetas se ignoran. Por lo tanto, dos estructuras que difieren solo en sus etiquetas se pueden convertir de una a otra. |
|
1.9–1.9.7 | 2017-08-24 |
| El compilador de Go ahora admite la compilación de las funciones de un paquete en paralelo, aprovechando múltiples núcleos. |
1.10–1.10.7 | 2018-02-16 |
| Para el puerto x86 de 64 bits, el ensamblador ahora admite 359 nuevas instrucciones, incluidos los conjuntos de extensión AVX, AVX2, BMI, BMI2, F16C, FMA3, SSE2, SSE3, SSSE3, SSE4.1 y SSE4.2 completos. El ensamblador tampoco se implementa más |
1.11–1.11.6 | 2018-08-24 | No hay cambios de idioma en esta versión. |
|
1.12.1 | 2019-02-25 | No hay cambios de idioma en esta versión. |
|
1.13.1 | 2019-09-03 | Go ahora admite un conjunto más uniforme y modernizado de prefijos literales numéricos |
|
1,14 | 2020-02-25 | Permite la incorporación de interfaces con conjuntos de métodos superpuestos. | El soporte del módulo en el |
1,15 | 2020-08-11 | No hay cambios de idioma en esta versión. |
|
1,16 | 2021-02-16 | No hay cambios de idioma en esta versión. |
|
1,17 | 2021-08-16 | No hay cambios de idioma en esta versión. |
|
Go está influenciado por C (especialmente el dialecto Plan 9), pero con énfasis en una mayor simplicidad y seguridad. El idioma consta de:
x := 0
lugar de int x = 0;
o var x = 0;
).go get
) y documentación de paquetes en línea.select
declaración.La sintaxis de Go incluye cambios de C destinados a mantener el código conciso y legible. Se introdujo un operador combinado de declaración / inicialización que permite al programador escribir i := 3
o s := "Hello, world!"
, sin especificar los tipos de variables utilizadas. Esto contrasta con C int i = 3;
y const char *s = "Hello, world!";
. Los puntos y comas todavía terminan declaraciones, pero están implícitos cuando se produce el final de una línea. Los métodos pueden devolver varios valores, y devolver un result, err
par es la forma convencional en que un método indica un error a su llamador en Go. Go agrega sintaxis literales para inicializar parámetros de estructura por nombre y para inicializar mapas y sectores. Como alternativa al for
ciclo de tres instrucciones de C, las range
expresiones de Go permiten una iteración concisa sobre matrices, cortes, cadenas, mapas y canales.
Go tiene varios tipos integrados, incluidos los numéricos ( byte, int64, float32, etc.), booleanos y cadenas de caracteres ( cadena). Las cadenas son inmutables; Los operadores y palabras clave incorporados (en lugar de funciones) proporcionan concatenación, comparación y codificación / decodificación UTF-8. Los tipos de registros se pueden definir con la palabra clave struct.
Para cada tipo T y cada constante entera no negativa n, hay un tipo de matriz denotado [ n ] T ; las matrices de diferentes longitudes son, por tanto, de diferentes tipos. Las matrices dinámicas están disponibles como "rebanadas", denotado [] T para algún tipo T. Estos tienen una longitud y una capacidad que especifican cuándo es necesario asignar nueva memoria para expandir la matriz. Varias secciones pueden compartir su memoria subyacente.
Los punteros están disponibles para todos los tipos, y el puntero-a- T tipo se denota * T. La toma de direcciones y la indirección utilizan los operadores amp; y *, como en C, o suceden implícitamente a través de la sintaxis de acceso a atributos o llamadas a métodos. No hay aritmética de puntero, excepto a través del tipo especial unsafe.Pointer en la biblioteca estándar.
Para un par de tipos K, V, el tipo map [ K ] V es el tipo de tablas hash que mapean claves de tipo- K con valores de tipo- V. Las tablas hash están integradas en el lenguaje, con una sintaxis especial y funciones integradas. chan T es un canal que permite enviar valores de tipo T entre procesos Go concurrentes.
Aparte de su soporte para interfaces, el sistema de tipos de Go es nominal : la palabra clave type se puede usar para definir un nuevo tipo con nombre, que es distinto de otros tipos con nombre que tienen el mismo diseño (en el caso de una estructura, los mismos miembros en el mismo orden). Algunas conversiones entre tipos (por ejemplo, entre los distintos tipos de enteros) están predefinidas y agregar un nuevo tipo puede definir conversiones adicionales, pero las conversiones entre tipos con nombre siempre deben invocarse explícitamente. Por ejemplo, la palabra clave type se puede usar para definir un tipo para direcciones IPv4, basado en enteros sin signo de 32 bits:
type ipv4addr uint32
Con esta definición de tipo, ipv4addr (x) interpreta el valor x de uint32 como una dirección IP. Simplemente asignar x a una variable de tipo ipv4addr es un error de tipo.
Las expresiones constantes pueden estar escritas o "sin escribir"; se les asigna un tipo cuando se asignan a una variable con tipo si el valor que representan pasa una verificación en tiempo de compilación.
Los tipos de función se indican mediante la palabra clave func ; toman cero o más parámetros y devuelven cero o más valores, todos los cuales se escriben. El parámetro y los valores de retorno determinan un tipo de función; por lo tanto, func (string, int32) (int, error) es el tipo de funciones que toman una cadena y un entero de 32 bits con signo, y devuelven un entero con signo (de ancho predeterminado) y un valor del tipo de interfaz incorporado error.
Cualquier tipo con nombre tiene un conjunto de métodos asociado. El ejemplo de dirección IP anterior se puede ampliar con un método para verificar si su valor es un estándar conocido:
// ZeroBroadcast reports whether addr is 255.255.255.255. func (addr ipv4addr) ZeroBroadcast() bool { return addr == 0xFFFFFFFF }
Debido a la escritura nominal, esta definición de método agrega un método a ipv4addr, pero no a uint32. Si bien los métodos tienen una definición especial y una sintaxis de llamada, no existe un tipo de método distinto.
Go proporciona dos características que reemplazan la herencia de clases.
La primera es la incrustación, que puede verse como una forma automatizada de composición o delegación.
El segundo son sus interfaces, que proporcionan polimorfismo en tiempo de ejecución. Las interfaces son una clase de tipos y proporcionan una forma limitada de tipificación estructural en el sistema de tipo de Go, por lo demás nominal. Un objeto que es de un tipo de interfaz también es de otro tipo, muy parecido a que los objetos de C ++ sean simultáneamente de una clase base y derivada. Las interfaces Go se diseñaron según los protocolos del lenguaje de programación Smalltalk. Varias fuentes utilizan el término escritura pato al describir las interfaces de Go. Aunque el término tipificación de pato no está definido con precisión y, por lo tanto, no es incorrecto, generalmente implica que la conformidad del tipo no se verifica estáticamente. Dado que el compilador de Go comprueba estáticamente la conformidad con una interfaz de Go (excepto cuando se realiza una aserción de tipo), los autores de Go prefieren el término tipado estructural.
La definición de un tipo de interfaz enumera los métodos necesarios por nombre y tipo. Cualquier objeto de tipo T para el que existan funciones que coincidan con todos los métodos requeridos de la interfaz de tipo I es también un objeto de tipo I. La definición de tipo T no necesita (y no puede) identificar el tipo I. Por ejemplo, si Forma, Cuadrado y Círculo se definen como
import "math" type Shape interface { Area() float64 } type Square struct { // Note: no "implements" declaration side float64 } func (sq Square) Area() float64 { return sq.side * sq.side } type Circle struct { // No "implements" declaration here either radius float64 } func (c Circle) Area() float64 { return math.Pi * math.Pow(c.radius, 2) }
entonces, tanto un Cuadrado como un Círculo son implícitamente una Forma y se pueden asignar a una variable de tipo Forma. En lenguaje formal, el sistema de interfaz de Go proporciona mecanografía estructural en lugar de nominal. Las interfaces pueden incrustar otras interfaces con el efecto de crear una interfaz combinada que se satisfaga exactamente con los tipos que implementan la interfaz incrustada y cualquier método que agregue la interfaz recién definida.
La biblioteca estándar de Go utiliza interfaces para proporcionar genérico en varios lugares, incluido el sistema de entrada / salida que se basa en los conceptos de Reader y Writer.
Además de llamar a métodos a través de interfaces, Go permite convertir valores de interfaz a otros tipos con una verificación de tipo en tiempo de ejecución. Las construcciones del lenguaje para hacerlo son la aserción de tipo, que se compara con un único tipo potencial, y el cambio de tipo, que se compara con varios tipos.
La interfaz vacía interface{}
es un caso base importante porque puede referirse a un elemento de cualquier tipo concreto. Es similar a la clase Object en Java o C # y se satisface con cualquier tipo, incluidos los tipos integrados como int. El código que usa la interfaz vacía no puede simplemente llamar a métodos (u operadores integrados) en el objeto al que se hace referencia, pero puede almacenar el interface{}
valor, intentar convertirlo a un tipo más útil a través de una afirmación de tipo o un cambio de tipo, o inspeccionarlo con el reflect
paquete de Go. Dado que interface{}
puede hacer referencia a cualquier valor, es una forma limitada de escapar de las restricciones de escritura estática, como void*
en C, pero con comprobaciones de tipo en tiempo de ejecución adicionales.
El interface{}
tipo se puede usar para modelar datos estructurados de cualquier esquema arbitrario en Go, como datos JSON o YAML, representándolo como un map[string]interface{}
(mapa de cadena a interfaz vacía). Esto describe datos de forma recursiva en forma de diccionario con claves de cadena y valores de cualquier tipo.
Los valores de la interfaz se implementan utilizando un puntero a los datos y un segundo puntero a la información del tipo de tiempo de ejecución. Al igual que algunos otros tipos implementados mediante punteros en Go, los valores de la interfaz están nil
sin inicializar.
En el sistema de paquetes de Go, cada paquete tiene una ruta (por ejemplo, "compress/bzip2"
o "golang.org/x/net/html"
) y un nombre (por ejemplo, bzip2
o html
). Las referencias a las definiciones de otros paquetes siempre deben ir precedidas del nombre del otro paquete, y solo se puede acceder a los nombres en mayúsculas de otros paquetes: io.Reader
es público pero bzip2.reader
no lo es. El go get
comando puede recuperar paquetes almacenados en un repositorio remoto y se anima a los desarrolladores a desarrollar paquetes dentro de una ruta base correspondiente a un repositorio de origen (como example.com/user_name/package_name) para reducir la probabilidad de colisión de nombres con futuras adiciones al estándar. biblioteca u otras bibliotecas externas.
Existen propuestas para introducir una solución de gestión de paquetes adecuada para Go similar a CPAN para el sistema de carga de Perl o Rust o el sistema npm de Node.
El lenguaje Go tiene funciones integradas, así como soporte de biblioteca, para escribir programas simultáneos. La concurrencia se refiere no solo al paralelismo de la CPU, sino también a la asincronía : permitir que se ejecuten operaciones lentas como una lectura de la base de datos o la red mientras el programa realiza otro trabajo, como es común en los servidores basados en eventos.
La construcción de concurrencia principal es la goroutine, un tipo de proceso ligero. Una llamada de función con el prefijo de la go
palabra clave inicia una función en una nueva goroutine. La especificación del lenguaje no especifica cómo deben implementarse las goroutines, pero las implementaciones actuales multiplexan las goroutines de un proceso Go en un conjunto más pequeño de subprocesos del sistema operativo, similar a la programación realizada en Erlang.
Mientras que un paquete de biblioteca estándar que presenta la mayoría de las estructuras clásicas de control de concurrencia ( bloqueos mutex, etc.) está disponible, los programas concurrentes idiomáticos prefieren canales, que proporcionan mensajes de envío entre gorutinas. Los búferes opcionales almacenan los mensajes en orden FIFO y permiten que el envío de goroutines continúe antes de que se reciban sus mensajes.
Los canales se escriben, por lo que un canal de tipo Chan T sólo puede ser usado para transferir mensajes de tipo T. Se utiliza una sintaxis especial para operar con ellos; lt;-ch es una expresión que hace que la goroutine en ejecución se bloquee hasta que ingrese un valor sobre el canal ch, mientras que ch lt;- x envía el valor x (posiblemente bloqueando hasta que otra goroutine reciba el valor). La declaración de selección de tipo interruptor incorporado se puede utilizar para implementar la comunicación sin bloqueo en múltiples canales; vea a continuación un ejemplo. Go tiene un modelo de memoria que describe cómo las rutinas deben usar canales u otras operaciones para compartir datos de forma segura.
La existencia de canales distingue a Go de lenguajes concurrentes al estilo de modelo de actor como Erlang, donde los mensajes se dirigen directamente a los actores (correspondientes a goroutines). El estilo de actor se puede simular en Go manteniendo una correspondencia uno a uno entre goroutines y canales, pero el lenguaje permite que múltiples goroutines compartan un canal o una sola goroutine para enviar y recibir en múltiples canales.
A partir de estas herramientas, se pueden crear construcciones simultáneas como grupos de trabajadores, canalizaciones (en las que, por ejemplo, un archivo se descomprime y analiza a medida que se descarga), llamadas en segundo plano con tiempo de espera, llamadas paralelas "desplegadas" a un conjunto de servicios y otras.. Los canales también han encontrado usos más allá de la noción habitual de comunicación entre procesos, como servir como una lista segura de simultaneidad de búferes reciclados, implementar corrutinas (que ayudaron a inspirar el nombre goroutine) e implementar iteradores.
Las convenciones estructurales de Go relacionadas con la concurrencia ( canales y entradas de canales alternativos) se derivan del modelo de procesos secuenciales de comunicación de Tony Hoare. A diferencia de los lenguajes de programación concurrente anteriores como Occam o Limbo (un lenguaje en el que trabajó el co-diseñador de Go, Rob Pike), Go no proporciona ninguna noción incorporada de concurrencia segura o verificable. Si bien el modelo de procesos de comunicación se ve favorecido en Go, no es el único: todas las gorutinas de un programa comparten un único espacio de direcciones. Esto significa que los objetos y punteros mutables se pueden compartir entre goroutines; ver § Falta de seguridad en las condiciones de carrera, más abajo.
Aunque las funciones de simultaneidad de Go no están destinadas principalmente al procesamiento paralelo, se pueden utilizar para programar máquinas multiprocesador de memoria compartida. Se han realizado varios estudios sobre la eficacia de este enfoque. Uno de estos estudios comparó el tamaño (en líneas de código ) y la velocidad de los programas escritos por un programador experimentado que no está familiarizado con el lenguaje y las correcciones de estos programas por parte de un experto en Go (del equipo de desarrollo de Google), haciendo lo mismo para Chapel, Cilk e Intel TBB. El estudio encontró que los no expertos tendía a escribir divide y vencerás algoritmos con un solo movimiento comunicado por la recursividad, mientras que el experto escribió programas de distribuir el trabajo a sincronizar usando uno goroutine por procesador. Los programas del experto solían ser más rápidos, pero también más largos.
No hay restricciones sobre cómo las goroutines acceden a los datos compartidos, lo que hace posible las condiciones de carrera. Específicamente, a menos que un programa se sincronice explícitamente a través de canales u otros medios, las escrituras de una goroutine pueden ser parcial, total o nada visibles para otra, a menudo sin garantías sobre el orden de las escrituras. Además, las estructuras de datos internas de Go, como los valores de interfaz, los encabezados de segmento, las tablas hash y los encabezados de cadena no son inmunes a las condiciones de carrera, por lo que la seguridad del tipo y la memoria se puede violar en programas multiproceso que modifican instancias compartidas de esos tipos sin sincronización. En lugar de soporte de lenguaje, la programación concurrente segura se basa en convenciones; por ejemplo, Chisnall recomienda un modismo llamado "alias xor mutable", lo que significa que pasar un valor mutable (o puntero) sobre un canal indica una transferencia de propiedad sobre el valor a su receptor.
El vinculador de la cadena de herramientas de gc crea binarios vinculados estáticamente de forma predeterminada; por lo tanto, todos los binarios de Go incluyen el tiempo de ejecución de Go.
Go omite deliberadamente ciertas características comunes en otros lenguajes, incluida la herencia (implementación), la programación genérica, las aserciones, la aritmética de punteros, las conversiones de tipos implícitas, las uniones sin etiquetar y las uniones etiquetadas. Los diseñadores agregaron solo aquellas instalaciones que los tres acordaron.
De las características del lenguaje omitidas, los diseñadores argumentan explícitamente en contra de las aserciones y la aritmética de punteros, mientras defienden la opción de omitir la herencia de tipos como un lenguaje más útil, alentando en cambio el uso de interfaces para lograr un envío dinámico y una composición para reutilizar el código. De hecho, la composición y la delegación se automatizan en gran medida mediante la incrustación de estructuras ; según los investigadores Schmager et al., esta característica "tiene muchos de los inconvenientes de la herencia: afecta la interfaz pública de los objetos, no es detallada (es decir, no hay control a nivel de método sobre la incrustación), los métodos de los objetos incrustados no se pueden ocultar y es estático ", por lo que" no es obvio "si los programadores lo abusarán en la medida en que los programadores de otros lenguajes tengan fama de abusar de la herencia.
Los diseñadores expresan su apertura a la programación genérica y señalan que las funciones integradas son de hecho genéricas de tipo, pero se tratan como casos especiales; Pike llama a esto una debilidad que puede cambiar en algún momento. El equipo de Google creó al menos un compilador para un dialecto Go experimental con genéricos, pero no lo lanzó. También están abiertos a estandarizar formas de aplicar la generación de código. En junio de 2020, se publicó un nuevo borrador de documento de diseño, que agregaría la sintaxis necesaria a Go para declarar funciones y tipos genéricos. Se proporcionó una herramienta de traducción de código go2go para permitir a los usuarios probar la nueva sintaxis, junto con una versión habilitada para genéricos de Go Playground en línea.
Inicialmente omitido, finalmente se agregó el mecanismo de pánico / recuperación similar a una excepción, que los autores de Go recomiendan usar para errores irrecuperables, como aquellos que deberían detener un programa completo o una solicitud del servidor, o como un atajo para propagar errores en la pila dentro de un paquete. (pero no a través de los límites del paquete; allí, las devoluciones de error son la API estándar).
Los autores de Go hicieron un esfuerzo sustancial para influir en el estilo de los programas de Go:
gofmt
herramienta estandariza automáticamente la sangría, el espaciado y otros detalles del código a nivel de superficie. golint
realiza comprobaciones de estilo adicionales automáticamente.godoc
), pruebas ( go test
), compilación ( go build
), administración de paquetes ( go get
), etc.map
y bloques try
/ estilo Java finally
) tiende a fomentar un estilo de programación particular, explícito, concreto e imperativo.La distribución principal de Go incluye herramientas para crear, probar y analizar código:
go build
, que crea binarios de Go utilizando solo la información de los archivos de origen, sin archivos MAKE separadosgo test
, para pruebas unitarias y microbenchmarksgo fmt
, para formatear el códigogo install
, para recuperar e instalar paquetes remotosgo vet
, un analizador estático que busca posibles errores en el códigogo run
, un atajo para compilar y ejecutar códigogodoc
, para mostrar documentación o servirla a través de HTTPgorename
, para cambiar el nombre de variables, funciones, etc. de forma segura para los tiposgo generate
, una forma estándar de invocar generadores de códigoTambién incluye soporte para la creación de perfiles y depuración, instrumentación en tiempo de ejecución (por ejemplo, para rastrear las pausas de recolección de basura ) y un probador de condición de carrera.
Un ecosistema de herramientas de terceros se suma a la distribución estándar, como, por ejemplo gocode
, que permite el autocompletado de código en muchos editores de texto goimports
, que agrega / elimina automáticamente las importaciones de paquetes según sea necesario y errcheck
que detecta código que podría ignorar errores involuntariamente.
package main import "fmt" func main() { fmt.Println("Hello, world!") }
donde "FMT" es el paquete de formato I / O, similar a la de C de entrada de archivo C / salida.
El siguiente programa simple demuestra las características de concurrencia de Go para implementar un programa asincrónico. Lanza dos hilos ligeros ("goroutines"): uno espera que el usuario escriba algún texto, mientras que el otro implementa un tiempo de espera. La instrucción select espera a que cualquiera de estas goroutines envíe un mensaje a la rutina principal y actúa sobre el primer mensaje que llega (ejemplo adaptado del libro de David Chisnall).
package main import ( "fmt" "time") func readword(ch chan string) { fmt.Println("Type a word, then hit Enter.") var word string fmt.Scanf("%s", amp;word) ch lt;- word } func timeout(t chan bool) { time.Sleep(5 * time.Second) t lt;- false } func main() { t:= make(chan bool) go timeout(t) ch:= make(chan string) go readword(ch) select { case word:= lt;-ch: fmt.Println("Received", word) case lt;-t: fmt.Println("Timeout.") } }
El paquete de prueba proporciona soporte para pruebas automatizadas de paquetes go. Ejemplo de función de destino:
func ExtractUsername(email string) string { at:= strings.Index(email, "@") return email[:at] }
Código de prueba (tenga en cuenta que falta la palabra clave assert en Go; las pruebas se encuentran en lt;filenamegt; _test.go en el mismo paquete):
import ( "testing") func TestExtractUsername(t *testing.T) { t.Run("withoutDot", func(t *testing.T) { username:= ExtractUsername("r@google.com") if username != "r" { t.Fatalf("Got: %v\n", username) } }) t.Run("withDot", func(t *testing.T) { username:= ExtractUsername("jonh.smith@example.com") if username != "jonh.smith" { t.Fatalf("Got: %v\n", username) } }) }
Es posible ejecutar pruebas en paralelo.
El paquete net / http brinda soporte para la creación de aplicaciones web.
Este ejemplo mostraría "¡Hola mundo!" cuando se visita localhost: 8080.
package main import ( "fmt" "log" "net/http") func helloFunc(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello world!") } func main() { http.HandleFunc("/", helloFunc) log.Fatal(http.ListenAndServe(":8080", nil)) }
Algunas aplicaciones notables de código abierto escritas en Go incluyen:
Otras empresas y sitios notables que utilizan Go (generalmente junto con otros idiomas, no exclusivamente) incluyen:
Consulte también la consulta relacionada con Wikidata.
El sistema de interfaz, y la omisión deliberada de la herencia, fueron elogiados por Michele Simionato, quien comparó estas características con las del ML estándar, calificándolo de "una vergüenza que ningún lenguaje popular haya seguido [esta] ruta en particular".
Dave Astels en Engine Yard escribió:
Go es extremadamente fácil de sumergirse. Hay un número mínimo de conceptos lingüísticos fundamentales y la sintaxis es limpia y está diseñada para ser clara e inequívoca. Go es todavía experimental y todavía un poco tosco en los bordes.
Go fue nombrado Lenguaje de programación del año por el Índice de la comunidad de programación TIOBE en su primer año, 2009, por tener un aumento de popularidad de 12 meses más grande (en solo 2 meses, después de su introducción en noviembre) que cualquier otro idioma ese año. y alcanzó el puesto 13 en enero de 2010, superando idiomas establecidos como Pascal. En junio de 2015, su clasificación había caído por debajo del puesto 50 en el índice, colocándolo por debajo de COBOL y Fortran. Pero a partir de enero de 2017, su clasificación había subido al puesto 13, lo que indica un crecimiento significativo en popularidad y adopción. Go fue galardonado con el lenguaje de programación TIOBE del año 2016.
Bruce Eckel ha declarado:
La complejidad de C ++ (se ha agregado aún más complejidad en el nuevo C ++) y el impacto resultante en la productividad ya no está justificado. Todos los obstáculos que tuvo que superar el programador de C ++ para utilizar un lenguaje compatible con C ya no tienen sentido: son solo una pérdida de tiempo y esfuerzo. Go tiene mucho más sentido para la clase de problemas que C ++ originalmente tenía la intención de resolver.
Una evaluación de 2011 del lenguaje y su implementación de gc en comparación con C ++ ( GCC ), Java y Scala por un ingeniero de Google encontró:
Go ofrece interesantes funciones de lenguaje, que también permiten una notación concisa y estandarizada. Los compiladores de este lenguaje aún son inmaduros, lo que se refleja tanto en el rendimiento como en los tamaños binarios.
- R. HundtLa evaluación recibió una refutación del equipo de desarrollo de Go. Ian Lance Taylor, que había mejorado el código de Go para el artículo de Hundt, no había sido consciente de la intención de publicar su código y dice que su versión "nunca tuvo la intención de ser un ejemplo de Go idiomático o eficiente"; Luego, Russ Cox optimizó el código Go, así como el código C ++, y logró que el código Go se ejecutara un poco más rápido que C ++ y más de un orden de magnitud más rápido que el código en el documento.
El 10 de noviembre de 2009, el día del lanzamiento general del lenguaje, Francis McCabe, desarrollador de Go! lenguaje de programación (nótese el signo de exclamación), solicitó un cambio de nombre del lenguaje de Google para evitar confusiones con su lenguaje, que había estado desarrollando durante 10 años. McCabe expresó su preocupación de que "el 'gran tipo' acabará aplastándolo", y esta preocupación resonó entre los más de 120 desarrolladores que comentaron sobre el hilo de problemas oficiales de Google diciendo que deberían cambiar el nombre, y algunos incluso dijeron el problema. contradice el lema de Google de: No seas malvado.
El 12 de octubre de 2010, el desarrollador de Google Russ Cox (@rsc) cerró el problema con el estado personalizado "Desafortunado" acompañado del siguiente comentario:
"Hay muchos productos y servicios informáticos llamados Go. En los 11 meses desde nuestro lanzamiento, ha habido una mínima confusión de los dos idiomas".
Van los críticos dicen que:
Un estudio muestra que es tan fácil crear errores de simultaneidad con el paso de mensajes como con la memoria compartida, a veces incluso más.
funkyprogrammer.uk / concurrencia-en- marcha -lenguaje-de-programación /
Este artículo incorpora material del tutorial oficial de Go, que tiene la licencia Creative Commons Attribution 3.0.![]() | Wikimedia Commons tiene medios relacionados con Go (lenguaje de programación). |