Decidí probar Go en mi viaje para aprender un nuevo idioma que fuera útil para mi carrera y mis intereses. Esta vez he estado probando Go. Creo que, como primera impresión, es bastante agradable.
Esta no es una visita guiada y, posiblemente, no está escrita para nadie más que para mí, como recordatorios personales.
Me propuse un pequeño proyecto llamado Os-Release-Q. Mi intención era poder tener un binario en cualquier sistema que administre, de modo que pueda imprimir exactamente la información que necesito, sin necesidad de analizarla o buscarla visualmente.
Buscar en la web habla mucho sobre importar paquetes de otras personas, pero muy poco sobre organizar el propio código. Incluso los médicos se centran en ir a buscar en lugar de separar las preocupaciones.
Encuentro este obstáculo bastante en todos los idiomas, ya que cada uno tiene su propia filosofía idiosincrásica sobre cómo abordarlo y qué limitaciones tiene o impone cada uno.
De todas las actividades que realicé para aprender los conceptos básicos, provenientes de una experiencia predominantemente en Python, dividir mi código en varios archivos fue lo que más me llevó más tiempo obtener respuestas. En resumen, encontré lo siguiente:
Para submódulos locales, el submódulo debe residir en una carpeta. Puede declarar un nombre de submódulo de paquete.
Digamos que está en src/submod/, con el implementador principal en src/submod/submod.go. En main.go importamos "nombre-módulo/src/submod" (con el nombre-módulo extraído de go.mod). Y luego podemos llamar a submod.SomeFunction().
Tenemos en cuenta que las funciones del submódulo solo están disponibles para los importadores si su nombre comienza con una letra en mayúscula. Así que no hagas submod.myFunction() - tiene que ser submod.MyFunction().
Seguramente hay otras consideraciones en torno a los submódulos y las importaciones, pero en cuanto a mantener el código organizado y segregado, esto es lo esencial.
Para mantener las cosas sensatas, tuve la tentación de tener solo un archivo que declarara el paquete principal y aislar el resto en submódulos; estos se importan automáticamente sin necesidad de declararlos en la lista de archivos FILES de Go Build.
Después de haber resuelto esta especificidad de Go, el resto encajó con bastante facilidad. Para cada tarea básica había, por supuesto, una entrada de StackOverflow o una página de GoByExample.com y, más básicamente, la referencia del lenguaje Go.
Dos tareas particularmente comunes merecen sus propios párrafos.
A menudo se comenta que el manejo de errores básico es engorroso y que literalmente requiere manejar errores en medio del flujo de control. Esto puede ser un anatema para los programadores que vienen de un flujo de trabajo try/catch, pero manejar el problema en el punto donde puede ocurrir no es tan malo.
// explicit return item `err` forces us to be aware of it // but having the ability to check it in the same breath is not so bad if result, err := someCall(); err != nil { log.Fatal("Sorry.") } // Equally valid is /* result, err := someCall() if err != nil { log.Fatal("Sorry") } */ fmt.Println(result)
Comparar modo intento/captura
try: result = someCall() print(result) except: print("Sorry") # a little divorced from potential origin of error sys.exit(1)
No puedo evitar sentir que la implementación de la biblioteca de banderas está un poco a medias. Evidentemente la gente está acostumbrada y está de acuerdo con ello, dada su supervivencia en su forma actual.
Llamar al programa -flag arg1 arg2 nos da la opción que el flag está configurado para hacer, y posicionales := flags.Args() nos devuelve la matriz de ["arg1", "arg2"]
Sin embargo, llamar al programa arg1 arg2 -flag no alterna lo que se supone que debe hacer -flags, y en su lugar proporciona posicionales como ["arg1", "arg2", "-flag"] donde la bandera no fue analizado.
Esto puede ser útil para pasar una subllamada como el programa colorize ls -l donde ls -l se transmite literalmente, para poder ver un caso de uso.
Es solo que la mayoría de los programas permiten argumentos de bandera en cualquier lugar alrededor de elementos posicionales. ls dir1/ -l dir2/ es lo mismo que ls -l dir1/ dir2/, y esta es una convención que se aplica a la gran mayoría de los comandos de Unix y Linux.
Puede ser que sea algo a lo que hay que acostumbrarse y que vale la pena mencionar.
Dejando a un lado el paradigma de importación de archivos, me resultó bastante fácil implementar mi aplicación básica. Todo lo que hice mal me pareció bastante obvio y los errores fueron significativos. Realmente siento que puedo concentrarme en "hacer las cosas".
A partir de mi escaso uso hasta ahora, y teniendo en cuenta mis necesidades específicas, puedo ver
Pensé que tener tipos dispersos en lugar de objetos y herencia sería un obstáculo, pero hasta ahora todo bien. Me las arreglo sin ellos en otros lenguajes, así que supongo que cuando llegue a definir interfaces y tipos, me sentiré como un paso adelante respecto a Lua y bash. Espero.
Una de las razones por las que quería explorar un lenguaje compilado en nativo era poder producir archivos binarios que pudieran desviarse fácilmente, sin necesidad de depender de una versión particular de un tiempo de ejecución presente.
Recientemente, un colega se acercó a mi escritorio consternado, tratando de resolver cómo colocar Java 17 en una antigua imagen base de Node que estaba basada en Debian 10. Tendría que actualizar la versión de Node para obtener una imagen base más nueva, usar una nueva imagen base de Debian e instalar y configurar Node manualmente, o buscar en Internet un repositorio personalizado alojado por Dios sabe quién para Dios sabe -Java 17 pirateado que se ejecutaría en Debian 10.
Cuánto más fácil sería si el software implementado no tuviera dependencias de tiempo de ejecución tan conflictivas...
Desde el punto de vista de las operaciones, la gran ganancia que creo que podría sentir es: puedo escribir código fácilmente y construir un binario ELF para luego implementarlo en un "sistema arbitrario X" y no tener que lidiar con él. garantizar que exista la versión correcta de un tiempo de ejecución determinado y gestionar dependencias en conflicto.
Estoy seguro de que hay otros beneficios, y he escuchado mucho sobre la facilidad de uso de multiproceso y multiprocesamiento en Go, y tengo la intención de preparar un mini proyecto para explorar eso como el siguiente paso. probablemente algo que pueda escuchar entradas en múltiples canales y realizar algunas tareas básicas en respuesta. He tenido un caso de uso para esto en algunas tareas de automatización de pruebas que he tenido antes, por lo que no me resulta ajeno en este momento.
Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.
Copyright© 2022 湘ICP备2022001581号-3