golang循环导包问题(import cycle not allowed)解决方案

本文章来为各位介绍关于golang不允许循环import问题(“import cycle not allowed”)问题的解决办法了,这个是语法问题各位可以来看看。
golang语法不允许循环import package,如果检测到import cycle 会在编译时报错,通常import cycle是因为设计错误或包的规划问题。
以下面的例子为例,package a依赖package b,同时package b依赖package a。

源码目录:

.
├── a
│   └── A.go
├── b
│   └── B.go
├── go.mod
├── go.sum
└── main.go

//A.go
package a
 
import (
  "fmt"
 
  "test/b"
)
 
type A struct {
}
 
func (a A) PrintA() {
  fmt.Println(a)
}
 
func NewA() *A {
  a := new(A)
  return a
}
 
func RequireB() {
  o := b.NewB()
  o.PrintB()
}
//B.go
package b
 
import (
  "fmt"
 
  "test/a"
)
 
type B struct {
}
 
func (b B) PrintB() {
  fmt.Println(b)
}
 
func NewB() *B {
  b := new(B)
  return b
}
 
func RequireA() {
  o := a.NewA()
  o.PrintA()
}
//main.go
package main

import (
    "fmt"
    "test/a"
)   

func main() {
    fmt.Println("<<<---")

    a.RequireB()
    //b.RequireA()
}  

就会在编译时报错:

root@helmsman:~/go/src/github.com/test# go build
package test
  	imports test/a
  	imports test/b
  	imports test/a: import cycle not allowed
  root@helmsman:~/go/src/github.com/test# 

现在的问题就是:

A depends on B
B depends on A

像mutex死锁一样,陷入了死循环

那么如何避免?

引入interface,例如package i

源码目录:

├── a
│   └── A.go
├── b
│   └── B.go
├── go.mod
├── go.sum
├── i
│   └── api.go
├── main.go
└── test

3 directories, 7 files
//api.go
package i

type Aprinter interface {
    PrintA()
}
//A.go
package a

import (
    "fmt"

    "test/b"
)

type A struct {
}

func (a A) PrintA() {
    fmt.Println("i am PrintA()", a)
}

func NewA() *A {
    a := new(A)
    return a
}

func RequireB() {
    fmt.Println("i am package a, call PrintB()")
    o := b.NewB()
    o.PrintB()
}

//B.go
package b

import (
    "fmt"
    "test/i"
)

type B struct {
}

func (b B) PrintB() {
    fmt.Println("i am PrintB()", b)
}

func NewB() *B {
    b := new(B)
    return b
}

func RequireA(i i.Aprinter) {
    fmt.Println("i am package b, call PrintA()")
    i.PrintA()
}

//main.go
package main

import (
    "fmt"
    "test/a"
    "test/b"
)

func main() {
    a.RequireB()
    fmt.Println()

    o1 := a.NewA()
    b.RequireA(o1)
}

现在依赖关系如下:

a depends on b
b depends on I
main depends on a and a

编译执行:

root@helmsman:~/go/src/github.com/filecoin-project/test/t# go build
root@helmsman:~/go/src/github.com/filecoin-project/test/# ./test 
i am package a, call PrintB()
i am PrintB() {}

i am package b, call PrintA()
i am PrintA() {}
root@helmsman:~/go/src/github.com/filecoin-project/test/# 
  • 9
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唐墨123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值