导入循环不允许

huangapple go评论88阅读模式
英文:

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 &lt;--- 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() // 错误 &lt;== 这就是问题所在。你已经在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 &lt;== 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 (
	&quot;go-circular-dependency/two&quot;
)

//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 (
	&quot;fmt&quot;
	&quot;go-circular-dependency/one&quot;
)

//Multiplier is going to be used in package one
func Multiplier() int {
	return 2
}

//Total is
func Total() {
    //import AddOne from &quot;package one&quot;
	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 (
	&quot;fmt&quot;
)

//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

我对此有另一个解决方案。

我的情况

  1. 我发现在开始项目之前我没有运行命令:go mod init <module_name>

  2. 后来我尝试导入“mux”包go get github/gorilla/mux,然后我得到了“不允许导入循环”的错误。

请检查您是否在您正在工作的目录中初始化了一个模块(参见第1点中的命令)。然后尝试运行脚本。

英文:

I got another solution for this.

My case

  1. I found out that I had not run the command : go mod init &lt;module_name&gt; before starting to work on the project.

  2. 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'

huangapple
  • 本文由 发表于 2015年2月1日 05:50:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/28256923.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定