web-dev-qa-db-fra.com

Comment implémenter une interface depuis un autre paquet dans golang?

Je suis débutant en golang et essayais des interfaces. Je souhaite conserver les interfaces dans des packages distincts afin de pouvoir l'utiliser pour l'implémenter dans divers autres packages, ainsi que pour les fournir aux autres équipes (fichier .a) afin qu'elles puissent implémenter des plugins personnalisés. S'il vous plaît voir exemple ci-dessous sur ce que je voudrais réaliser.

--- Folder structure ---
gitlab.com/myproject/
                  interfaces/
                            shaper.go
                  shapes/
                        rectangle.go
                        circle.go

---- shaper.go ---
package interfaces

type Shaper interface{

    Area() int

}

Comment puis-je m'assurer que rectangle.go implémente l'interface de shaper? Je comprends que go implémente implicitement les interfaces. Cela signifie-t-il que rectangle.go implémente automatiquement shaper.go même s’il se trouve dans un package différent?

Je l'ai essayé comme ci-dessous, mais lorsque j'exécute l'outil gofmt, il supprime l'importation, car il n'est pas utilisé.

--- rectangle.go ---
package shapes

import "gitlab.com/myproject/interfaces"

type rectangle struct{

  length int
  width int
}

func (r rectangle) Area() int {
 return r.length * r.width
}

Merci d'avance.

4
Sanketh

Il y a une excellente section dans le go wiki à propos des interfaces:

Les interfaces Go appartiennent généralement au package qui utilise les valeurs du type d'interface, pas le package qui implémente ces valeurs. Le package d'implémentation doit renvoyer des types concrets (généralement un pointeur ou une structure): de cette manière, de nouvelles méthodes peuvent être ajoutées aux implémentations sans nécessiter de refactoring approfondi.

Cela présente également l’avantage de réduire le couplage entre les packages (en n’obligeant personne à importer votre package uniquement pour l’interface) et en générant généralement des interfaces plus petites (en permettant aux utilisateurs de ne consommer qu’un sous-ensemble de l’interface que vous auriez créée). .

Si vous débutez, je vous recommande vivement de lire l’article de wiki "Go Code Review Comments" que j’ai lié et si vous avez encore un peu de temps/ Effective Go . Bonne piratage!

11
Friedrich Große

Disons que vous avez une fonction qui utilise une Shaper. Vous pouvez tester la fonction avec une rectangle et ainsi assurer la mise en œuvre:

func DoStuff(s Shaper) {
    s.Area()
}

func TestDoStuff(t *testing.T) {
    var s Shaper = rectangle{length: 5, width: 3}
    DoStuff(s)
    // assertion
}

Si rectangle n'implémente pas Shaper, vous obtiendrez une erreur comme celle-ci:

cannot use rectangle literal (type rectangle) as type Shaper in assignment:
rectangle does not implement Shaper (missing Area method)

Effective Go :

Interfaces in Go provide a way to specify the behavior of an object: if something can do this, then it can be used here.

0
Lan Quach