回答編集履歴

3

書式改善

2022/05/06 00:26

投稿

nobonobo
nobonobo

スコア3367

test CHANGED
@@ -7,16 +7,30 @@
7
7
  - AがBをインポート
8
8
  - BがAをインポート
9
9
 
10
+ これはインポート依存を矢印で図示してみるとAー>Bー>Aー>Bー>・・・と延々と終端にたどり着けない状態を指します。
11
+
12
+ ## 既存の言語とGoの違い
13
+
10
14
  既存の言語処理系では循環インポートをエラーとしないものが多いのですが、
11
- これはコンパイル時間を遅くすることや、コードから本質的な依存関係を把握しにくくなるということで
15
+ これはコンパイル時間を遅くすることや、コードから本質的な依存関係を
12
- Goではエラー扱いにするという仕様を採択しています。
16
+ 把握しにくくなるということで**Goではエラー扱いにするという仕様を採択しています。**
13
17
 
14
18
  なので、解決するには循環インポートしている実装を循環しないようにするしかありません。
15
19
 
16
- 解決案1(初心者向け):パッケージの分割をやめてまとめる
17
- 解決案2:局所的な依存定義をさらに別のパッケージに分割
18
20
 
19
- 後者の
21
+ ## 決案
22
+
23
+ - 解決案1(初心者向け):パッケージの分割をやめてまとめる
24
+ - 解決案2:局所的な依存定義をさらに別のパッケージに分割
25
+
26
+ ### 解決案1の解説
27
+
28
+ 例えばAパッケージにa1、a2の定義が書かれていて、Bパッケージにb1、b2の定義が書かれているとして、
29
+ a1がa2とb1を利用したい、b2がa2を利用したい実装があるとすると、この状況をそのまんま実装するとAとBの循環インポートが生まれます。
30
+ そこでAパッケージにa1、a2、b1、b2の定義を全部入れ込んでしまうと循環参照は発生しなくなります。
31
+ ちなみにファイルは分割されていてもよくて、同じフォルダに多くのファイルを詰め込むという解決方法です。
32
+
33
+ ### 解決案2の解説
20
34
 
21
35
  例えばAパッケージにa1、a2の定義が書かれていて、Bパッケージにb1、b2の定義が書かれているとして、
22
36
  a1がa2とb1を利用したい、b2がa2を利用したい実装があるとすると、この状況をそのまんま実装するとAとBの循環インポートが生まれます。

2

解説追記

2022/05/06 00:15

投稿

nobonobo
nobonobo

スコア3367

test CHANGED
@@ -10,3 +10,15 @@
10
10
  既存の言語処理系では循環インポートをエラーとしないものが多いのですが、
11
11
  これはコンパイル時間を遅くすることや、コードから本質的な依存関係を把握しにくくなるということで
12
12
  Goではエラー扱いにするという仕様を採択しています。
13
+
14
+ なので、解決するには循環インポートしている実装を循環しないようにするしかありません。
15
+
16
+ 解決案1(初心者向け):パッケージの分割をやめてまとめる
17
+ 解決案2:局所的な依存定義をさらに別のパッケージに分割
18
+
19
+ 後者の解説
20
+
21
+ 例えばAパッケージにa1、a2の定義が書かれていて、Bパッケージにb1、b2の定義が書かれているとして、
22
+ a1がa2とb1を利用したい、b2がa2を利用したい実装があるとすると、この状況をそのまんま実装するとAとBの循環インポートが生まれます。
23
+ こういう時、a2の定義をCパッケージとして分離すると、A->C、A->B->Cという依存関係になり循環しなくなります。
24
+

1

補足追記

2022/05/06 00:07

投稿

nobonobo
nobonobo

スコア3367

test CHANGED
@@ -7,3 +7,6 @@
7
7
  - AがBをインポート
8
8
  - BがAをインポート
9
9
 
10
+ 既存の言語処理系では循環インポートをエラーとしないものが多いのですが、
11
+ これはコンパイル時間を遅くすることや、コードから本質的な依存関係を把握しにくくなるということで
12
+ Goではエラー扱いにするという仕様を採択しています。