44

Goプロジェクトに1か月取り組んでいます。良いことは、Go が非常に効率的であることです。しかし、1 か月の開発の後、私はすでに数千行のコードと多くのpackages. インポート サイクルを回避することは私にとって大きな問題です。インポート サイクル エラーが発生するたびに、最初は問題がどこにあるのかわかりません。

また、Go コンパイラには、次のような問題をすばやく特定するには常に十分ではない、非常に単純な通知しかありませんmain.go:7:3: import cycle not allowed。どのファイルが問題を引き起こしているかを知るのに役立つだけで、それ以上深くはなりません. importコードが成長するにつれて関係はますます複雑になるため、Go でインポート サイクルをより効率的に回避する方法を知りたいと思っています。どんな助けでも大歓迎です。

4

4 に答える 4

58
go list -f '{{join .Deps "\n"}}' <import-path>

-が空のまま<import-path>の場合は現在のディレクトリにあるパッケージのインポート依存関係を表示します。<import-path>あるいは

go list -f '{{join .DepsErrors "\n"}}' <import-path>

うまくいけば、あなたの場合に役立つ情報が表示されます。の出力も参照してください

go help list

go list ツールに関する追加情報については、 を参照してください。

于 2013-04-23T12:15:11.907 に答える
44

jnml の回答 (循環参照の問題を「デバッグ」するのに役立ちます) を補完するために、依存関係の反転を使用して、依存関係の注入と組み合わせて、これらのサイクルを断ち切ることができます。アプリケーションについては、私は常にクリーン アーキテクチャのガイドラインに従うようにしています - Go 固有の例については、こちらを参照してください- そして、Go のインターフェイスの「非宣言実装」 (つまり、明示的に言う必要がないこと) を見つけました。type MyStruct struct implements IfceSomething) を使用すると、これが非常に簡単になります。

したがって、パッケージがある場合はA -> B -> C -> AInterfaceAパッケージ C に (関連する名前、明らかに、パッケージ関連よりも動作に関連するもの:) を作成し、パッケージ A ではなくこのインターフェイスに依存させ、パッケージ A が「実装することを確認します。 「このインターフェース。

次に、ある時点でAからCへの具体的な実装を提供する必要があります(ここでは多くの可能性があります。通常、すべての依存関係を認識しているメインパッケージでこの「接着剤」コードを実行します)。

于 2013-04-23T17:27:18.497 に答える
0

go list ツールを使用して、既に知っている依存関係を確認するのはさておき、サブコンポーネントを構築することで、依存関係ツリーが十分に深いことを確認したいアーキテクチャの観点から。モジュールにインポート サイクルがある場合は、存在するサイクルを明確にする必要があります。これらの依存関係の移動がシームレスに機能するように、十分なモジュール性 (ツリーの深さ) が必要です。

Model -> Field  (Uses A) -- Needs to import "System"
Model -> System (Defines A) -- But needs to import "Field"
----------Move type A Struct A.go to top of module----------
----------This is what the Model Dir looks like now---------
Model -> A
Model -> Field
Model -> System

これで依存関係が分離され、子供たちは A を自由に使用できるようになりました。これは、依存関係を視覚化するのに役立たないか、ツールベースの優れたソリューションにはならないかもしれませんが、ロジックを十分に切り離してサブコンポーネントを構築すれば、サイクルをかなり迅速に収束させることができます。それ以外の場合、ツリー ビジュアライザーを使用している場合、それは最後の手段であり、設計が不十分である/サブコンポーネントが不十分であることが原因であると言えます。

于 2021-01-03T20:03:54.730 に答える