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 aimport ("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 bimport ("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 mainimport ("fmt""test/a"
)   func main() {fmt.Println("<<<---")a.RequireB()//b.RequireA()
}  

就会在编译时报错:

root@helmsman:~/go/src/github.com/test# go build
package testimports test/aimports test/bimports test/a: import cycle not allowedroot@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
└── test3 directories, 7 files
//api.go
package itype Aprinter interface {PrintA()
}
//A.go
package aimport ("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 bimport ("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 mainimport ("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/# 


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部