英文:
Import cycle not allowed
问题
我有一个问题:
> import cycle not allowed
当我尝试测试我的控制器时出现了这个问题。以下是输出内容:
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
我该如何阅读或理解这个错误?依赖关系出了什么问题?
英文:
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?
答案1
得分: 285
这是你的第一个导入循环问题的示例。
project/controllers/account
^ \
/ \
/ \
/ \/
project/components/mux <--- project/controllers/base
正如你在我的糟糕的 ASCII 图表中所看到的,当 project/components/mux
导入 project/controllers/account
时,你创建了一个导入循环。由于 Go 不支持循环依赖,所以在编译时会出现 import cycle not allowed
错误。
英文:
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.
答案2
得分: 171
我刚遇到了这个问题。你可能正在使用包名来访问同一包中的方法/类型。
这里有一个例子来说明我的意思:
在foo.go中:
// foo.go
package foo
func Foo() {...}
在foo_test.go中:
// foo_test.go
package foo
// 尝试访问Foo()
foo.Foo() // 错误 <== 这就是问题所在。你已经在foo包中,没有必要使用foo.Foo()来访问Foo()
Foo() // 正确
循环依赖的另一个常见原因在这个答案中有所展示。
与JavaScript不同,Go对循环依赖的容忍度较低,这既是好事也是坏事。
英文:
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.
答案3
得分: 16
这是一个循环依赖的问题。Golang程序必须是无环的。在Golang中,不允许循环导入(也就是说,它的导入图不能包含任何循环)。
假设你的项目go-circular-dependency
有两个包,"package one"和它的"one.go",以及"package two"和它的"two.go"。所以你的项目结构如下所示:
+--go-circular-dependency
+--one
+-one.go
+--two
+-two.go
当你尝试做以下操作时,就会出现这个问题。
步骤1 - 在one.go
中导入package two
(以下是one.go
的内容)
package one
import (
"go-circular-dependency/two"
)
//AddOne函数
func AddOne() int {
a := two.Multiplier()
return a + 1
}
步骤2 - 在two.go
中导入package one
(以下是two.go
的内容)
package two
import (
"fmt"
"go-circular-dependency/one"
)
//Multiplier函数将在package one中使用
func Multiplier() int {
return 2
}
//Total函数
func Total() {
//从package one中导入AddOne函数
x := one.AddOne()
fmt.Println(x)
}
在步骤2中,你将收到一个错误信息:"can't load package: import cycle not allowed"(这被称为**"循环依赖"错误**)。
从技术上讲,这是一个糟糕的设计决策,你应该尽量避免这种情况,但你可以通过隐式接口来**"打破循环依赖"**(个人不推荐,强烈反对这种做法,因为按设计,Go程序必须是无环的)。
尽量保持你的导入依赖浅层。当依赖图变得更深时(即包x导入y,y导入z,z导入x),循环依赖就更有可能发生。
有时候代码重复并不是一个坏主意,这与DRY(不要重复自己)的原则恰恰相反。
所以在步骤2中的two.go
中,你不应该导入package one。相反,在two.go
中,你应该复制one.go
中的AddOne()
函数的功能,如下所示:
package two
import (
"fmt"
)
//Multiplier函数将在package one中使用
func Multiplier() int {
return 2
}
//Total函数
func Total() {
// x := one.AddOne()
x := Multiplier() + 1
fmt.Println(x)
}
英文:
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)
}
答案4
得分: 5
你可能已经在project/controllers/routes
中导入了project/controllers/base
。你之前已经导入过了,这是不支持的。
英文:
You may have imported,
project/controllers/base
inside the
project/controllers/routes
You have already imported before. That's not supported.
答案5
得分: 5
错误 这个错误是由两个模块同时相互导入引起的。
模块A导入模块B
模块B导入模块A
解决方案 找到一种方法将双向导入改为单向导入。
英文:
Error The error results from having two modules importing each other simultaneously.
Module A importing Module B
Module B importing Module A
Solution Find a way to make the two way imports a one way import.
答案6
得分: 2
我对此有另一个解决方案。
我的情况
-
我发现在开始项目之前我没有运行命令:
go mod init <module_name>
。 -
后来我尝试导入“mux”包
go get github/gorilla/mux
,然后我得到了“不允许导入循环”的错误。
请检查您是否在您正在工作的目录中初始化了一个模块(参见第1点中的命令)。然后尝试运行脚本。
英文:
I got another solution for this.
My case
-
I found out that I had not run the command :
go mod init <module_name>
before starting to work on the project. -
Later I was trying to import the "mux" package
go get github/gorilla/mux
and then I was getting the error "Import cycle not allowed".
Check if you have initialized a module( the command mentioned in pt 1.) if required in the directory that you are working. Then try running the script.
答案7
得分: 2
导入循环的原因已经在上面的回答中提到了。
在运行命令 go build -mod vendor
时,我遇到了内置库的导入循环问题。
例如:
...
...
导入 github.com/aws/aws-sdk-go/aws
导入 net/http
导入 crypto/tls
导入 crypto/ecdsa
导入 crypto/elliptic
导入 crypto/internal/nistec
导入 crypto/elliptic: 不允许导入循环
...
...
导入 fmt
导入 errors
导入 internal/reflectlite
导入 runtime
导入 internal/abi
导入 internal/goarch
导入 bytes
导入 errors: 不允许导入循环
通过卸载并重新安装golang来解决了这个问题。我想在之前没有正确安装golang。感谢 https://bytemeta.vip/repo/fyne-io/fyne/issues/3089 中的提示。我无法在那里给予那个人信用,但在这里提一下。谢谢。
英文:
Reason for import cycle has been mentioned in above answers.
I was facing import cycle issue for built-in lib while running a command go build -mod vendor
Ex:
...
...
imports github.com/aws/aws-sdk-go/aws
imports net/http
imports crypto/tls
imports crypto/ecdsa
imports crypto/elliptic
imports crypto/internal/nistec
imports crypto/elliptic: import cycle not allowed
...
...
imports fmt
imports errors
imports internal/reflectlite
imports runtime
imports internal/abi
imports internal/goarch
imports bytes
imports errors: import cycle not allowed
It was solved by uninstalling golang and reinstalling it. I think I didnt install the golang correctly before. Thanks for the hint in https://bytemeta.vip/repo/fyne-io/fyne/issues/3089. I couldnt give credits to that person there but mentioning here. Thanks.
答案8
得分: 1
有时候你使用命令 'go mod init x/y/z' 给出了相同的模块名,而且你的导入(import)也是相同的。这对我来说至少很难解决。
只需给你的模块取一个有意义的名字,例如 'go mod init sid'。
英文:
Sometimes you give the same module name using command ' go mod init x/y/z' and you have the same import as well. This was very hard to solve at least for me.
Just give any meaningful name to your mod e.g, 'go mod init sid'
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论