Go 不允许导入周期
我有一个问题 不允许导入周期 当我试着测试我的控制器时,它出现了。以下是输出:Go 不允许导入周期,go,Go,我有一个问题 不允许导入周期 当我试着测试我的控制器时,它出现了。以下是输出: 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
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
如何阅读或理解此错误?依赖项哪里错了?这是第一个导入周期问题的示例
project/controllers/account
^ \
/ \
/ \
/ \/
project/components/mux <--- project/controllers/base
project/controller/account
^ \
/ \
/ \
/ \/
project/components/mux我刚刚遇到了这个问题。您可能正在使用包名本身从同一个包中访问方法/类型
下面是一个例子来说明我的意思:
在foo.go中:
// foo.go
package foo
func Foo() {...}
在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
//foo_test.go
打包食品
//尝试访问Foo()
foo.foo()//错误您可能已导入
project/controllers/base
内部
project/controllers/routes
您以前已经导入过。这是一个循环依赖性问题。Golang计划必须是非循环的。在Golang中,不允许循环导入(即其导入图不得包含任何循环)
假设您的项目go循环依赖项
有两个包“package one”&它有“one.go”和“package two”&它有“two.go”,因此您的项目结构如下
+--go-circular-dependency
+--one
+-one.go
+--two
+-two.go
当您尝试执行以下操作时,就会出现此问题
步骤1-在one.go
中导入包2
(以下是one.go
)
步骤2-在two.go
中导入package one
(以下是two.go
)
在步骤2中,您将收到一个错误“无法加载包:不允许导入周期”
(这称为“循环依赖”错误)
从技术上讲,这是一个糟糕的设计决策,您应该尽可能避免这种情况,但您可以“通过隐式接口打破循环依赖”(我个人不建议,并且强烈反对这种做法,因为按设计进行的程序必须是非循环的)
尽量使导入依赖关系保持浅。当依赖关系图变得更深时(即包x导入y,y导入z,z导入x),则更可能出现循环依赖关系
有时代码重复是个不错的主意,这与DRY正好相反(不要重复你自己)
因此,在步骤2中,即two.go中,您不应该导入包1。相反,在two.go
中,您应该实际复制AddOne()
中编写的one.go
的功能,如下所示
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)
}
我找到了另一个解决方案。
我的案子
我发现在开始处理项目之前,我没有运行命令:go mod init
后来,我尝试导入“mux”包go-get-github/gorilla/mux
,然后出现错误“import cycle not allowed”
如果需要,检查您是否已在正在工作的目录中初始化模块(第1部分中提到的命令)。然后尝试运行脚本。account
包导入base
包,后者导入mux
包,后者导入account
包。这是一组周期性的导入依赖项,这是不允许的。看起来您还有另一个循环,base
导入mux
,导入路由
,导入base
。这只在编译时出现。浪费了很多时间重组我的hole项目,只是为了看到我不被允许做我所做的事情。。。达福…这是我不喜欢去的原因之一。这只是十几个原因中的一个。允许循环DEP将显著增加编译时间,因为每次更改一个DEP时,整个DEP循环都需要重新编译。拥有循环DEP也是一个沉重的认知负担,因为它使你更难对你的程序进行推理,并趋于复杂。你使用的是哪根线?我看不到vs code上有任何线。我可以通过watcher
运行应用程序时看到这个错误。在我看来,这是更好的答案。公认的答案同样有效,但除了解释这种失败的理论之外,没有任何其他解释@然而,乔纳森·林的回答完美地解释了这个神秘的错误信息,以及如何应对它。现在是2020年,我认为这应该是一个更好的、被接受的答案@StackOverflow这个答案只给出了循环导入的一个实例,它是最简单的一个,一个导入自身的包。大多数情况下,当您遇到此错误时,您会删除许多软件包,了解如何解释此错误将使您比了解错误如何发生的一个实例更进一步。谢谢您的回答,但是由于可维护性,我喜欢干式方法。对于我来说,说“有时候代码重复不是个坏主意”并不好,因为如果我在12个结构组之间有共同的功能,我必须在每个结构组中编写12次,并更新12次代码。是的。12点左右你是对的。但是,如果它在不同的服务中只有2或3个,有时情况就不那么糟糕了。就像在DB中创建一个标准化级别较低的表,但避免额外的连接来优化它。“通过隐式接口打破循环依赖”(我个人不建议,并且强烈反对这种做法,因为按照设计,Go程序必须是非循环的)。这是Go的技术限制,而不是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)
}
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)
}