有三个结构:A(package a)
,B(package b)
,C(package c)
。
B
想要使用C
的功能,C
想要使用B
的功能。
A
有 B
和 C
实例,所以 B
可以访问 C
的功能> 通过 A
反之亦然。
我使用了在另一个 package i
中声明的接口(interface) Ageter
,它的函数声明为 GetA() *a.A
现在我在 B
和 C
中使用这个接口(interface) Ageter
,通过它我得到 A
的实例和访问功能C
和B
。
package a
import (
"fmt"
"basics/importCycleIssue/issueFix/b"
"basics/importCycleIssue/issueFix/c"
)
type A struct {
B *b.B
C *c.C
}
var a = NewA()
func NewA() *A {
a := &A{}
a.B = b.NewB(a)
a.C = c.NewC(a)
return a
}
func GetA() *A{
return a
}
---------------------------------------------------
package b
import (
"fmt"
"basics/importCycleIssue/issueFix/i"
)
type B struct {
o i.Ageter
}
func NewB(o i.Ageter) *B {
b := &B{o: o}
return b
}
func (b *B) UseC() {
fmt.Println("need to use C:",b.o.GetA().C)
}
----------------------------------------------------
package c
import (
"fmt"
"basics/importCycleIssue/issueFix/i"
)
type C struct {
o i.Ageter
}
func NewC(o i.Ageter) *C {
c := &C{o: o}
return c
}
func (c *C) UseB() {
fmt.Println("need to use B:",c.o.GetA().B)
}
----------------------------------------------------
package i
import (
"basics/importCycleIssue/issueFix/a"
)
type Aprinter interface {
PrintA()
}
type Ageter interface {
GetA() *a.A
}
---------------------------------------------------
package main
import (
"basics/importCycleIssue/issueFix/a"
)
func main() {
o := a.NewA()
o.B.UseC()
o.C.UseB()
}
我应该能够在 C
中使用 B
的功能,反之亦然。
构建代码时出现import cycle not allowed
错误。
不允许导入循环
包主
导入基础知识/importCycleIssue/issueFix/a
导入基础知识/importCycleIssue/issueFix/b
导入基础知识/importCycleIssue/issueFix/i
导入基础知识/importCycleIssue/issueFix/a
谁能告诉我如何解决这个问题?
谢谢。
最佳答案
您快完成了,但我认为您可能误解了应该如何使用接口(interface)来修复循环依赖性。您已经定义了直接引用具体类型 的接口(interface),因此依赖循环仍然存在。让 i
依赖于 a
并不能解决问题,它只是扩展了循环依赖。
让我们回到您的核心问题:
B wants to use functionality of C and C wants to use functionality of B. A has both B and C instances, so that B can access functionality of C via A and vice versa.
您需要使用新包 i
来定义接口(interface)仅。这些接口(interface)应仅相互引用 - 不对 A、B 或 C 的引用。B 和 C 应仅引用 i 中的接口(interface)类型- 没有对 A、B 或 C 的引用。因此,我必须为所有 3 个包中的必要类型定义接口(interface)。例如:
package i
import (
)
type A interface {
GetB() B
GetC() C
}
type B interface {
UseC()
}
type C interface {
UseB()
}
---------------------------------------------------
package a
import (
"fmt"
"basics/importCycleIssue/issueFix/b"
"basics/importCycleIssue/issueFix/c"
"basics/importCycleIssue/issueFix/i"
)
type A struct {
B *b.B
C *c.C
}
func NewA() *A {
a := &A{}
a.B = b.NewB(a)
a.C = c.NewC(a)
return a
}
// These methods implement i.A and return the i.B and i.C interface types
func (a A) GetB() i.B {
return a.B
}
func (a A) GetC() i.C {
return a.C
}
---------------------------------------------------
package b
import (
"fmt"
"basics/importCycleIssue/issueFix/i"
)
type B struct {
a i.A
}
func NewB(a i.A) *B {
b := &B{a: a}
return b
}
func (b *B) UseC() {
fmt.Println("need to use C:",b.a.GetC())
}
----------------------------------------------------
package c
import (
"fmt"
"basics/importCycleIssue/issueFix/i"
)
type C struct {
a i.A
}
func NewC(a i.A) *C {
c := &C{a: a}
return c
}
func (c *C) UseB() {
fmt.Println("need to use B:",c.a.GetB())
}
关于go - 如何解决导入周期不允许的问题,尽管我正在使用界面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54130194/