0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Go】import cycle not allowedが発生する原因と解決策

Posted at

はじめに

import cycle not allowedというエラーに遭遇したため、備忘録としてまとめます。

この記事におけるGoのバージョンは以下のとおりです。

% go version
go version go1.24.2 darwin/arm64

問題

パッケージのimport文でimport cycle not allowedというコンパイルエラーが発生してしまう。

image.png

解決策

循環参照が発生してしまっているため、以下のような対応が必要。

  • 原因となっている型や機能を他のパッケージへ移動させる
  • 原因となっている型や機能を新しいパッケージへ切り出す
  • インターフェースを利用して依存関係の向きを変える
  • パッケージ構成の全面的な見直し

エラーの詳細

import cycle not allowedはパッケージ間で循環参照が発生していることを意味します。

循環参照とは、複数のパッケージがお互いをインポートしている状態です。

直接的な循環参照

たとえば次のコードでは、パッケージabがお互いをインポートしているため、import cycle not allowedが発生します。

a/a.go
package a

import (
	"fmt"
	"go-sample/b"
)

func PrintA() {
	fmt.Println("Function PrintA called")
	b.PrintB()
}
b/b.go
package b

import (
	"fmt"
	"go-sample/a"
)

func PrintB() {
	fmt.Println("Function PrintB called")
	a.PrintA()
}

上記2ファイルでgo vet ./...を実行するとエラーが発生します。

% go vet ./...
package go-sample/a
        imports go-sample/b from a.go
        imports go-sample/a from b.go: import cycle not allowed

間接的な循環参照

上記は直接的な循環参照ですが、パッケージabcがa→b→c→aのようにインポートしている場合も循環参照となります。

a/a.go
package a

import (
	"fmt"
	"go-sample/b"
)

func PrintA() {
	fmt.Println("Function PrintA called")
	b.PrintB()
}
b/b.go
package b

import (
	"fmt"
	"go-sample/c"
)

func PrintB() {
	fmt.Println("Function PrintB called")
	c.PrintC()
}
c/c.go
package c

import (
	"fmt"
	"go-sample/a"
)

func PrintC() {
	fmt.Println("Function PrintC called")
	a.PrintA()
}

上記3ファイルでgo vet ./...を実行するとエラーが発生します。

% go vet ./...
package go-sample
        imports go-sample/a from main.go
        imports go-sample/b from a.go
        imports go-sample/c from b.go
        imports go-sample/a from c.go: import cycle not allowed

なぜ循環参照がダメなのか?

循環参照があると、Goのコンパイラはパッケージをビルドする際に依存関係を解決できません。

どのパッケージからビルドを開始すればよいか分からないからです。

また循環参照が発生するということは、パッケージ間の依存関係が複雑になりすぎている兆候であり、ソフトウェア設計の観点でも好ましくないです。

そのためGoでは意図的に禁止されています。

おわりに

この記事ではimport cycle not allowedが発生する原因と解決策についてまとめました。

参考になれば幸いです。

このエラーに頻繁に遭遇するようであれば、パッケージ構成に改善の余地があるかもしれません。

アーキテクチャを見直す機会とするのも有効だと思いました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?