Importcyclus niet toegestaan

Ik heb een probleem met

importcyclus niet toegestaan

Het verschijnt wanneer ik mijn controller probeer te testen. Hier is de uitvoer:

can't load package: import cycle not allowed
package project/controllers/account
    imports project/controllers/base
    imports project/components/mux
    imports project/controllers/account
import cycle not allowed
package project/controllers/account
    imports project/controllers/base
    imports project/components/mux
    imports project/controllers/account
import cycle not allowed
package project/controllers/account
    imports project/controllers/base
    imports project/components/mux
    imports project/controllers/routes
    imports project/controllers/base

Hoe kan ik deze fout lezen of begrijpen? Waar is de afhankelijkheid verkeerd?


Antwoord 1, autoriteit 100%

Hier is een illustratie van uw eerste probleem met de importcyclus.

                 project/controllers/account
                     ^                    \    
                    /                      \
                   /                        \ 
                  /                         \/
         project/components/mux <--- project/controllers/base

Zoals je kunt zien aan mijn slechte ASCII-grafiek, creëer je een importcyclus wanneer project/components/muxproject/controllers/accountimporteert. Aangezien Go geen circulaire afhankelijkheden ondersteunt, krijg je tijdens het compileren de fout import cycle not allowed.


Antwoord 2, autoriteit 60%

Ik kwam dit net tegen. Mogelijk benadert u een methode/type vanuit hetzelfde pakket met behulp van de pakketnaam zelf.

Hier is een voorbeeld om te illustreren wat ik bedoel:

In foo.go:

// foo.go
package foo
func Foo() {...}

In foo_test.go:

// foo_test.go
package foo
// try to access Foo()
foo.Foo() // WRONG <== This was the issue. You are already in package foo, there is no need to use foo.Foo() to access Foo()
Foo() // CORRECT

Een andere veelvoorkomende oorzaak van circulaire afhankelijkheid wordt getoond in dit antwoord.

In tegenstelling tot JavaScript heeft Go een lage tolerantie voor circulaire afhankelijkheden, wat zowel een goede als een slechte zaak is.


Antwoord 3, autoriteit 4%

Dit is een kwestie van circulaire afhankelijkheid. Golang-programma’s moeten acyclisch zijn. In Golang zijn cyclische importen niet toegestaan ​​(dat wil zeggen dat de importgrafiek geen lussen mag bevatten)

Stel dat uw project go-circular-dependency2 pakketten “package one” & het heeft “one.go” & “pakket twee” & het heeft “two.go” Dus uw projectstructuur is als volgt

+--go-circular-dependency    
      +--one    
         +-one.go
      +--two        
         +-two.go

Dit probleem doet zich voor wanneer u iets als het volgende probeert te doen.

Stap 1– In one.goimporteert u package two(Hierna volgt one.go)

package one
import (
    "go-circular-dependency/two"
)
//AddOne is
func AddOne() int {
    a := two.Multiplier()
    return a + 1
}

Stap 2– In two.goimporteert u package one(Hierna volgt two.go)

package two
import (
    "fmt"
    "go-circular-dependency/one"
)
//Multiplier is going to be used in package one
func Multiplier() int {
    return 2
}
//Total is
func Total() {
    //import AddOne from "package one"
    x := one.AddOne()
    fmt.Println(x)
}

In stap 2 krijg je de foutmelding “kan pakket niet laden: importcyclus niet toegestaan”
(Dit wordt de ‘Circular Dependency’-foutgenoemd)

Technisch gezien is dit een slechte ontwerpbeslissing en je moet dit zoveel mogelijk vermijden, maar je kunt “circulaire afhankelijkheden doorbreken via impliciete interfaces” (ik raad deze praktijk persoonlijk niet aan, en raad het ten zeerste af, omdat door het ontwerp Go-programma’s moet acyclisch zijn)

Probeer uw importafhankelijkheid oppervlakkig te houden. Wanneer de afhankelijkheidsgrafiek dieper wordt (d.w.z. pakket x importeert y, y importeert z, z importeert x), dan worden circulaire afhankelijkheden waarschijnlijker.

Soms is het herhalen van codes geen slecht idee, wat precies het tegenovergestelde is van DRY (herhaal jezelf niet)

Dus in Stap 2dat is in two.gomoet je pakket één niet importeren. In plaats daarvan zou je in two.gode functionaliteit van AddOne()geschreven in one.goals volgt moeten repliceren.

package two
import (
    "fmt"
)
//Multiplier is going to be used in package one
func Multiplier() int {
    return 2
}
//Total is
func Total() {
    // x := one.AddOne()
    x := Multiplier() + 1
    fmt.Println(x)
}

Antwoord 4, autoriteit 2%

Je hebt misschien geïmporteerd,

project/controllers/base

in de

project/controllers/routes

Je hebt al eerder geïmporteerd. Dat wordt niet ondersteund.


Antwoord 5

Ik heb hier een andere oplossing voor.

Mijn zaak

  1. Ik kwam erachter dat ik het commando: go mod init <module_name>niet had uitgevoerd voordat ik aan het project begon.

  2. Later probeerde ik het “mux”-pakket go get github/gorilla/muxte importeren en toen kreeg ik de foutmelding “Import cycle not allowed”.

Controleer of je een module hebt geïnitialiseerd (het commando genoemd in punt 1.) indien nodig in de directory waarin je werkt. Probeer dan het script uit te voeren.


Antwoord 6

Soms geef je dezelfde modulenaam met het commando ‘go mod init x/y/z’ en heb je dezelfde import. Dit was in ieder geval voor mij erg moeilijk op te lossen.
Geef gewoon een betekenisvolle naam aan je mod, bijvoorbeeld ‘go mod init sid’

Other episodes