2 Ways to resolve "import cycle not allowed" in Golang

Source: Internet
Author: User

This article also publishes a personal CSDN blog: https://blog.csdn.net/ggq89/article/details/81148558

Believe that Gopher a lot of writing Golang procedures have encountered import cycle not allowed problems, I recently studied go-ethereum source code, found that the definition interface can also solve the problem, but also to solve the situation can not be solved even sub-package, and the score package is more simple and fast. The following are explained individually and in both 分包 定义接口 ways.

1. Application Scenarios

Suppose you have the following usage scenarios:

    1. AIs the framework-level structure of the application, which A contains the sub-modules B and C pointers;
    2. BIn order to facilitate the use of other sub-modules (such as) the application of the C function, so in its structure contains A the pointer;
    3. CTo invoke A a method in the package;

2. Code implementation

The procedure is broadly as follows:

    • package aThe code is as follows:
package aimport (    "fmt"    "github.com/ggq89/mutualdep/b"    "github.com/ggq89/mutualdep/c")type A struct {    Pb *b.B    Pc *c.C}func New(ic int) *A {    a := &A{        Pc: c.New(ic),    }    a.Pb = b.New(a)    return a}func Printf(v int) {    fmt.Printf("%v", v)}
    • package bThe code is as follows:
package bimport (    "github.com/ggq89/mutualdep/a")type B struct {    Pa *a.A}func New(a *a.A) *B {    return &B{        Pa: a,    }}func (b *B) DisplayC() {    b.Pa.Pc.Show()}
    • package cThe code is as follows:
package cimport "github.com/ggq89/mutualdep/a"type C struct {    Vc int}func New(i int) *C {    return &C{        Vc: i,    }}func (c *C) Show() {    a.Printf(c.Vc)}

package aDependent package b and package c , at the same time, dependent package b package a , package c also dependent package a .

mainThe function code is as follows:

package mainimport "github.com/ggq89/mutualdep/a"func main() {    a := a.New(3)    a.Pb.DisplayC()}

At compile time, the error will be as follows:

import cycle not allowedpackage main    imports github.com/ggq89/mutualdep/a    imports github.com/ggq89/mutualdep/b    imports github.com/ggq89/mutualdep/a

3. Defining the interface

Now the question is:

A depends on B B depends on A

For A struct and B struct with each other's pointers to this interdependence problem, you can use the method of defining the interface to solve the following steps:

    • package b a interface b All the variables and methods used in the structure are a translated into the method of using the interface, and the a a interface missing method is added in;

After the above steps are processed, the package b code is as follows:

package bimport (    "github.com/ggq89/mutualdep/c")type B struct {    Pa a}type a interface {    GetC() *c.C}func New(a a) *B {    return &B{        Pa:a,    }}func (b *B) DisplayC() {    b.Pa.GetC().Show()}
    • package acomplementary methods that may be missing in the process;

After processing, package a the code in is as follows:

package aimport (    "fmt"    "github.com/ggq89/mutualdep/b"    "github.com/ggq89/mutualdep/c")type A struct {    Pb *b.B    Pc *c.C}func New(ic int) *A {    a := &A{        Pc:c.New(ic),    }    a.Pb = b.New(a)    return a}func (a *A)GetC() *c.C {    return a.Pc}func Printf(v int)  {    fmt.Printf("%v", v)}

4. Splitting the package

Compile again with the following hints:

import cycle not allowedpackage main    imports github.com/ggq89/mutualdep/a    imports github.com/ggq89/mutualdep/b    imports github.com/ggq89/mutualdep/c    imports github.com/ggq89/mutualdep/a

Now is another interdependent issue:

A depends on C C depends on A

Unlike the previous interdependence, the preceding dependencies are A struct B struct caused by and have each other's pointers, which are hard interdependent;

And here is due to package c methods in the method call package a in the method, which belong to the soft mutual dependence;

    • This interdependence can be solved by splitting the method into another package, and in the process of splitting the package, the method of the struct body may be transformed into a normal function;

Introduce package f , migrate the method to f medium:

package fimport "fmt"func Printf(v int) {    fmt.Printf("%v", v)}

After the method package f is moved, package a the code is as follows:

package aimport (    "github.com/ggq89/mutualdep/b"    "github.com/ggq89/mutualdep/c")type A struct {    Pb *b.B    Pc *c.C}func New(ic int) *A {    a := &A{        Pc: c.New(ic),    }    a.Pb = b.New(a)    return a}func (a *A) GetC() *c.C {    return a.Pc}

package cpackage fIt is changed to a call with the following code:

package cimport (    "github.com/ggq89/mutualdep/a/f")type C struct {    Vc int}func New(i int) *C {    return &C{        Vc: i,    }}func (c *C) Show() {    f.Printf(c.Vc)}

Now the dependencies are as follows:

At this point, both package dependencies are resolved.

5. Summary

    1. For the soft mutual dependence, the use of subcontracting method can be solved, some functions caused by mutual dependence can only be solved by subcontracting, sub-package can refine the function of the package;

    2. For the hard mutual dependence can only be solved by defining the interface, defining the interface can improve the independence of the package, and also improve the difficulty of tracking the code call relationship;

Reference article:

    • Golang does not allow circular import issues ("Import cycle not Allowed"): http://ju.outofmemory.cn/entry/230115
    • Golang a way to solve the import cycle not allowed: Https://studygolang.com/articles/10582?fr=sidebar
    • Golang ("Import cycle not Allowed") Error: https://blog.csdn.net/skh2015java/article/details/53943784
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.