golang循环导包问题(import cycle not allowed)解决方案
程序员文章站
2022-05-29 22:18:10
...
本文章来为各位介绍关于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()
}
就会在编译时报错:
[email protected]:~/go/src/github.com/test# go build
package test
imports test/a
imports test/b
imports test/a: import cycle not allowed
[email protected]:~/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
编译执行:
[email protected]:~/go/src/github.com/filecoin-project/test/t# go build
[email protected]:~/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() {}
[email protected]:~/go/src/github.com/filecoin-project/test/#
上一篇: go 读取文件
下一篇: 批量管理工具pssh入门