不允许导入周期

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

如何阅读或理解此错误?依赖哪里错了?

这是第一个导入周期问题的说明。

                  project/controllers/account
                     ^                    \    
                    /                      \
                   /                        \ 
                  /                         \/
         project/components/mux <--- project/controllers/base
            
                   

正如您在我的错误 ASCII 图表中看到的那样,您在 project/components/mux 导入 project/controllers/account 时创建了一个导入周期。由于 Go 不支持循环依赖,因此您在编译期间会遇到 import cycle not allowed 错误。

我刚遇到这个。您可能正在使用包名称本身从同一包中访问 method/type。

这里有一个例子来说明我的意思:

在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

循环依赖的另一个常见原因如 所示。

与JavaScript不同,Go 对循环依赖的容忍度较低,这既是好事也是坏事。

您可能已经导入,

project/controllers/base

里面
project/controllers/routes

您之前已经导入过。不支持。

这是一个循环依赖问题。 Golang 程序必须是非循环的。在 Golang 中不允许循环导入(即它的导入图不能包含任何循环)

假设你的项目go-circular-dependency有2个包“包一”&它有“one.go”和“包二”&它有“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 is
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 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)
}

在第 2 步中,您将收到错误消息“无法加载包:不允许导入周期” (这称为“循环依赖”错误

从技术上讲,这是一个糟糕的设计决策,您应该尽可能避免这种情况,但您可以“通过隐式接口打破循环依赖”(我个人不推荐,并且强烈反对这种做法,因为设计Go程序必须是非循环的)

尽量减少对导入的依赖。当依赖图变得更深(即包 x 导入 y,y 导入 z,z 导入 x)时,循环依赖变得更有可能。

有时候代码重复并不是个坏主意,这与 DRY 正好相反(不要重复自己)

因此,在 two.go 中的 步骤 2 中,您不应导入包一。相反,在 two.go 中,您实际上应该复制 one.go 中编写的 AddOne() 的功能,如下所示。

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)
}

我找到了另一个解决方案。

我的案例

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

  2. 后来我尝试导入“mux”包 go get github/gorilla/mux 然后我收到错误“不允许导入周期”。

检查您是否已经在您正在工作的目录中初始化了一个模块(第 1 部分中提到的命令)。然后尝试 运行ning 脚本。

有时您使用命令“go mod init x/y/z”给出相同的 module 名称,并且您也有相同的导入。至少对我来说,这很难解决。 只需为您的 mod 提供任何有意义的名称,例如 'go mod init sid'

错误错误是由于两个模块同时导入对方造成的。

Module A importing Module B
Module B importing Module A

解决方案想办法把双向导入变成单向导入。