简体   繁体   中英

Golang Circular import structs

My code is simple.

Project/
    main.go
    pokemons/
        pokemon.go
    pokeTrainers/
        pokeTrainer.go

I have some Pokemon trainers which are defined like this :

package pokeTrainers

import "../pokemons"

type PokeTrainer struct {
    name        string
    pokemon    []Pokemon
}

And some Pokemon :

package pokemons

import "../pokeTrainers"

type Pokemon struct {
    name            string
    pokeTrainers    PokeTrainer
    }

main package is:

package main

import (
    "fmt"
    "./pokemons"
    "./pokeTrainers"
)

func main() {
    fmt.Printf("ERROR CIRCULAR IMPORT")

As always when I have an error, I copy-paste it on google. I learn what's a circular import and how people fix it with interface to use methods from another package without import it. But in my case, the problem is not to use methods but a real Type defined in another package.

So you will probably say: "Man you are dumb ! You just have to put everything on the same package and it's fine !" Sorry, I come from Java and I would like that my code stays clean. ;)

I saw this link which suggest to use a third party packages ? But you have to imagine that I don't have only pokemon and pokeTrainer, I have many more packages with a type inside and a lot of methods..

What do you think ? How can I fix this error proprelly ? I'm a beginner in Go

Either use a single package , so no import is needed.

Or designate one of your packages to be a "master", and put "everything" that is needed from both packages into this "master", and so only the other package needs to import "master" by definition (and "master" doesn't need to import the other).

Or you have to create a 3rd package for the stuff that is needed from both, and your 2 current packages only have to import this 3rd common package.

PS And don't use relative imports. Always use the complete package path.

I suggest you using interface for Pokemon. Perhaps you will add a several type of a pokemon and PokeTrainer should to train each one.

Example:

poketrainer.go

package pokeTrainers

type IPokemon interface {
    train() error
}

type PokeTrainer struct {
   name        string
   pokemon    []IPokemon
}

pokemon.go

package pokemons

import "github.com/pokemonWorld/pokeTrainers"

type Pikachu struct {
   name   string
   sensei *PokeTrainer
}

func (o *Pikachu) train() error {
   // your code here
}

One extra point of a recommendation - use a pointer of structure but not as a value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM