Supongamos que tiene un paquete mypack con dos archivos fuente mypack/a.go y mypack/b.go. Ambos archivos de origen dependen el uno del otro, pero el compilador de Go no se queja. Si divide ese paquete en dos, apack/a.go y bpack/b.go, el compilador de Go dirá import cycle not allowed.

Mi comprensión de cómo se manejan las dependencias de paquetes es que el compilador construirá un gráfico de las importaciones. Se analiza el gráfico y de alguna manera (¡me encantaría conocer el algoritmo que hace esto!) Se calcula el orden de compilación. El orden no se puede calcular si hay un ciclo en el gráfico, por lo que el compilador se queja.

Lo que no entiendo es cómo el compilador de Go puede resolver las dependencias entre las fuentes de un paquete, pero no puede resolver las dependencias entre los paquetes. Si las dos fuentes dependen la una de la otra, entonces tienes que hacer algunas acrobacias locas y compilarlas ambas al mismo tiempo de alguna manera.

¿Podría alguien aclararme esto?

-2
Indiana Kernick 16 oct. 2018 a las 10:37

2 respuestas

La mejor respuesta

[...] cómo el compilador de Go puede resolver dependencias entre fuentes de un paquete, pero no puede resolver dependencias entre paquetes. Si las dos fuentes dependen la una de la otra, entonces tienes que hacer algunas acrobacias locas y compilarlas ambas al mismo tiempo de alguna manera.

La pregunta se basa en suposiciones incorrectas sobre cómo se estructura y compila el código Go: un archivo fuente no no tiene una dependencia por definición. Un paquete tiene dependencias (todas las importaciones de todos sus archivos fuente). Las dependencias son paquetes (no archivos fuente). Para compilar un paquete, todas las dependencias deben estar disponibles antes que comience la compilación.

Realmente debes dejar de pensar en términos de archivos fuente. Los archivos fuente no tienen (casi) ningún significado en cómo se compila el código Go. La fuente de un paquete puede consistir en uno o varios archivos fuente y este es básicamente el punto único donde los archivos fuente ingresan compilando código Go. Todo lo relevante gira en torno a paquetes y solo paquetes: compila paquetes, importa paquetes, etc.

(Solo para completar: las etiquetas de compilación funcionan en el nivel de fuente y la inicialización del paquete puede depender de la organización del código fuente y al invocar manualmente gc puede hacer más que a través de la herramienta go).

3
Volker 16 oct. 2018 a las 08:13

Un paquete se compila como una sola unidad, independientemente de cuántos archivos fuente se utilicen. Esto no debería ser tan misterioso.

Además, su afirmación de que "el orden no se puede calcular si hay un ciclo" es simplemente incorrecta. Es trivial calcular tales cosas; muchos idiomas lo hacen. Go prohíbe esto, sin embargo, como una cuestión de política, porque conduce a un acoplamiento estrecho de código y código que es difícil de entender, no porque sea imposible.

1
Flimzy 16 oct. 2018 a las 07:46