Import cycle not allowed
I have a problem with
import cycle not allowed
It appears when I am trying to test my controller. Here is the output:
can't load package: import cycle not allowed
package project/controllers/account
imports project/controllers/base
imports project/components/mux
imports project/controllers/account
import cycle not allowed
package project/controllers/account
imports project/controllers/base
imports project/components/mux
imports project/controllers/account
import cycle not allowed
package project/controllers/account
imports project/controllers/base
imports project/components/mux
imports project/controllers/routes
imports project/controllers/base
How do I read or understand this error? Where is the dependency wrong?
Here is an illustration of your first import cycle problem.
project/controllers/account
^ \
/ \
/ \
/ \/
project/components/mux <--- project/controllers/base
As you can see with my bad ASCII chart, you are creating an import cycle when project/components/mux
imports project/controllers/account
. Since Go does not support circular dependencies you get the import cycle not allowed
error during compile time.
I just encountered this. You may be accessing a method/type from within the same package using the package name itself.
Here is an example to illustrate what I mean:
In foo.go:
// foo.go
package foo
func Foo() {...}
In foo_test.go:
// foo_test.go
package foo
// try to access Foo()
foo.Foo() // WRONG <== This was the issue. You are already in package foo, there is no need to use foo.Foo() to access Foo()
Foo() // CORRECT
Another common cause of circular dependency is shown in this answer.
Unlike JavaScript, Go has low tolerance for circular dependencies, which is both a good and a bad thing.
This is a circular dependency issue. Golang programs must be acyclic. In Golang cyclic imports are not allowed (That is its import graph must not contain any loops)
Lets say your project go-circular-dependency
have 2 packages "package one" & it has "one.go" & "package two" & it has "two.go" So your project structure is as follows
+--go-circular-dependency
+--one
+-one.go
+--two
+-two.go
This issue occurs when you try to do something like following.
Step 1 - In one.go
you import package two
(Following is one.go
)
package one
import (
"go-circular-dependency/two"
)
//AddOne is
func AddOne() int {
a := two.Multiplier()
return a + 1
}
Step 2 - In two.go
you import package one
(Following is two.go
)
package two
import (
"fmt"
"go-circular-dependency/one"
)
//Multiplier is going to be used in package one
func Multiplier() int {
return 2
}
//Total is
func Total() {
//import AddOne from "package one"
x := one.AddOne()
fmt.Println(x)
}
In Step 2, you will receive an error "can't load package: import cycle not allowed" (This is called "Circular Dependency" error)
Technically speaking this is bad design decision and you should avoid this as much as possible, but you can "Break Circular Dependencies via implicit interfaces" (I personally don't recommend, and highly discourage this practise, because by design Go programs must be acyclic)
Try to keep your import dependency shallow. When the dependency graph becomes deeper (i.e package x imports y, y imports z, z imports x) then circular dependencies become more likely.
Sometimes code repetition is not bad idea, which is exactly opposite of DRY (don't repeat yourself)
So in Step 2 that is in two.go
you should not import package one. Instead in two.go
you should actually replicate the functionality of AddOne()
written in one.go
as follows.
package two
import (
"fmt"
)
//Multiplier is going to be used in package one
func Multiplier() int {
return 2
}
//Total is
func Total() {
// x := one.AddOne()
x := Multiplier() + 1
fmt.Println(x)
}
You may have imported,
project/controllers/base
inside the
project/controllers/routes
You have already imported before. That's not supported.