Циклические зависимости между источниками пакета - PullRequest
0 голосов
/ 16 октября 2018

Допустим, у вас есть пакет mypack с двумя исходными файлами mypack/a.go и mypack/b.go.Оба этих исходных файла зависят друг от друга, но компилятор Go не жалуется.Если вы разделите этот пакет на два, apack/a.go и bpack/b.go, компилятор Go скажет import cycle not allowed.

Мое понимание того, как обрабатываются зависимости пакета, состоит в том, что компилятор построит график импорта,График анализируется и каким-то образом (я бы хотел узнать об алгоритме, который делает это!) Вычисляется порядок компиляции.Порядок не может быть рассчитан, если в графике есть цикл, поэтому компилятор жалуется.

Что я не понимаю, так это то, как компилятор Go может разрешать зависимости между источниками пакета, но не может разрешатьзависимости между пакетами.Если эти два источника зависят друг от друга, тогда вам нужно заняться какой-нибудь сумасшедшей акробатикой и каким-то образом скомпилировать их одновременно.

Может кто-нибудь объяснить мне это?

Ответы [ 2 ]

0 голосов
/ 16 октября 2018

[...] как компилятор Go может разрешать зависимости между источниками пакета, но не может разрешать зависимости между пакетами.Если два источника зависят друг от друга, тогда вам нужно заняться сумасшедшей акробатикой и как-то скомпилировать их одновременно.

Вопрос основан на неверных предположениях о том, как структурирован и скомпилирован код Go: исходный файл имеет не имеетзависимость по определению.Пакет имеет зависимости (все импортируются из всех его исходных файлов).Зависимости - это пакеты (не исходные файлы).Для компиляции пакета все зависимости должны быть доступны до начала компиляции.

Вы действительно должны перестать думать с точки зрения исходных файлов.Исходные файлы не имеют (почти) никакого смысла в том, как компилируется код Go.Исходный код пакета может состоять из одного или нескольких исходных файлов, и это, по сути, точка only , где исходные файлы входят в компиляцию кода Go.Все релевантное касается только пакетов и пакетов: вы компилируете пакеты, импортируете пакеты и т. Д.

(Просто для полноты: теги сборки работают на уровне исходного кода, а инициализация пакета может зависеть от организации исходного кода и ручного вызова gcВы можете сделать больше, чем с помощью инструмента go.)

0 голосов
/ 16 октября 2018

Пакет скомпилирован как единое целое, независимо от того, сколько исходных файлов используется.Это на самом деле не должно быть таким загадочным.

Кроме того, ваше утверждение, что «ордер не может быть рассчитан, если есть цикл», просто неверно.Подсчитать такие вещи тривиально - так делают многие языки.Однако Go запрещает это, исходя из политики, поскольку это приводит к тесной связи кода и кода, который трудно понять, а не потому, что это невозможно.

...