不允许导入周期

时间:2015-01-31 21:50:08

标签: 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 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

有人可以告诉我,如何阅读或理解这个错误?依赖在哪里错了?

5 个答案:

答案 0 :(得分:114)

以下是您的第一个导入周期问题的说明。

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

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

答案 1 :(得分:46)

我刚刚遇到这个。您可能正在使用包名本身从同一包中访问方法/类型。

这是一个说明我的意思的例子:

在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

答案 2 :(得分:3)

这是一个循环依赖性问题。 Golang程序必须是非循环的。在Golang中,不允许循环导入(也就是说,其导入图不得包含任何循环)

假设您的项目go-circular-dependency有2个软件包“ 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 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中复制用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)
}

答案 3 :(得分:1)

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

我的情况

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

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

如果需要,请检查您是否在您正在工作的目录中初始化了一个模块(pt 1 中提到的命令)。然后尝试运行脚本。

答案 4 :(得分:0)

您可能已经导入,

project/controllers/base

内部
project/controllers/routes

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