222 votes

Comment importer des paquets locaux sans gopath

J'ai utilisé GOPATH mais pour le problème actuel auquel je suis confronté, cela ne m'aide pas. Je veux pouvoir créer des paquets qui sont spécifiques à un projet :

myproject/
 binary1.go
 binary2.go
 package1.go
 package2.go

J'ai essayé de multiples façons mais comment obtenir package1.go pour travailler dans le binary1.go ou le binary2.go et ainsi de suite ?

Par exemple, je veux pouvoir import "package1" et ensuite être capable d'exécuter go build binary1.go et tout fonctionne bien sans que l'erreur soit lancée, à savoir que le paquet ne peut pas être trouvé sur GOROOT o GOPATH . La raison pour laquelle j'ai besoin de ce type de fonctionnalité est pour les projets à grande échelle ; je ne veux pas avoir à référencer plusieurs autres paquets ou les conserver dans un grand fichier.

185voto

Allez le résumé de la gestion des dépendances :

  • vgo si votre version de go est : x >= go 1.11
  • dep o vendor si votre version de go est : go 1.6 >= x < go 1.11
  • Manuellement si votre version de go est : x < go 1.6

Edit 3 : Go 1.11 a une fonctionnalité vgo qui remplacer dep .

Pour utiliser vgo voir Modules documentation. TLDR ci-dessous :

export GO111MODULE=on
go mod init
go mod vendor # if you have vendor/ folder, will automatically integrate
go build

Cette méthode crée un fichier appelé go.mod dans votre répertoire de projets. Vous pouvez ensuite construire votre projet avec go build . Si GO111MODULE=auto est définie, alors votre projet ne peut pas être dans $GOPATH .


Edit 2 : La méthode de vente est toujours valable et fonctionne sans problème. vendor est en grande partie un processus manuel, pour cette raison dep y vgo ont été créés.


Edit 1 : Bien que mon ancienne méthode fonctionne, ce n'est plus la manière "correcte" de le faire. Vous devriez utiliser vendeur capacités, vgo o dep (pour l'instant) qui sont activés par défaut dans Go 1.6 ; voir . En fait, vous ajoutez vos paquets "externes" ou "dépendants" à l'intérieur d'un fichier de type vendor lors de la compilation, le compilateur utilisera ces paquets en premier.


Trouvé. J'ai pu importer le paquet local avec GOPATH en créant un sous-dossier de package1 et ensuite l'importer avec import "./package1" en binary1.go y binary2.go scripts comme ceci :

binary1.go

...
import (
        "./package1"
      )
...

Ma structure de répertoire actuelle ressemble donc à ceci :

myproject/
├── binary1.go
├── binary2.go
├── package1/
│   └── package1.go
└── package2.go

Je dois également noter que les chemins relatifs (au moins dans go 1.5) fonctionnent également ; par exemple :

import "../packageX"

75voto

zzzz Points 23017

Le "paquet local" n'existe pas. L'organisation des paquets sur un disque est orthogonale à toute relation parent/enfant des paquets. La seule véritable hiérarchie formée par les paquets est l'arbre de dépendance, qui dans le cas général ne reflète pas l'arbre des répertoires.

Il suffit d'utiliser

import "myproject/packageN"

et ne combattez pas le système de construction sans raison valable. Economiser une douzaine de caractères par importation dans tout programme non trivial n'est pas une bonne raison, car, par exemple, les projets avec des chemins d'importation relatifs ne sont pas go-gettables.

Le concept des chemins d'importation a quelques propriétés importantes :

  • Les chemins d'importation peuvent être uniques au niveau mondial.
  • En conjonction avec GOPATH, le chemin d'importation peut être traduit sans ambiguïté en un chemin de répertoire.
  • Tout chemin de répertoire sous GOPATH peut être traduit sans ambiguïté en un chemin d'importation.

Tout ce qui précède est gâché par l'utilisation de chemins d'importation relatifs. Ne le faites pas.

PS : Il y a peu d'endroits dans le code hérité dans les tests du compilateur Go qui utilisent les importations relatives. ATM, c'est la seule raison pour laquelle les importations relatives sont supportées.

54voto

Juan Jose Tugores Points 536

Vous essayez peut-être de modulariser votre paquet. Je suppose que package1 y package2 font, d'une certaine manière, partie du même paquet, mais pour des raisons de lisibilité, vous les divisez en plusieurs fichiers.

Si le cas précédent était le vôtre, vous pourriez utiliser le même nom de paquet dans ces multiples fichiers et ce sera comme s'il s'agissait du même fichier.

Voici un exemple :

add.go

package math

func add(n1, n2 int) int {
   return n1 + n2
}

soustraire.go

package math

func subtract(n1, n2 int) int {
    return n1 - n2
}

donothing.go

package math

func donothing(n1, n2 int) int {
    s := add(n1, n2)
    s = subtract(n1, n2)
    return s
}

Je ne suis pas un expert en Go et c'est mon premier message dans StackOveflow, donc si vous avez des conseils, ils seront bien accueillis.

51voto

Tanver Hasan Points 306

Depuis l'introduction de la go.mod Je pense que la gestion des paquets locaux et externes devient plus facile. Utilisation de go.mod il est également possible d'avoir un projet de go en dehors du GOPATH.

Importer le paquet local :

Créer un dossier projet de démonstration et exécutez la commande suivante pour générer go.mod fichier

go mod init demoproject

J'ai une structure de projet comme ci-dessous à l'intérieur du projet de démonstration répertoire.

├── go.mod
└── src
    ├── main.go
    └── model
        └── model.go

Pour les besoins de la démonstration, insérez le code suivant dans le fichier modèle.go fichier.

package model

type Employee struct {
    Id          int32
    FirstName   string
    LastName    string
    BadgeNumber int32
}

Sur main.go J'ai importé le modèle d'employé en faisant référence à "demoproject/src/model".

package main

import (
    "demoproject/src/model"
    "fmt"
)

func main() {
    fmt.Printf("Main Function")

    var employee = model.Employee{
        Id:          1,
        FirstName:   "First name",
        LastName:    "Last Name",
        BadgeNumber: 1000,
    }
    fmt.Printf(employee.FirstName)
}

Importer une dépendance externe :

Il suffit de courir go get dans le répertoire du projet.

Par exemple :

go get -u google.golang.org/grpc

Il doit inclure la dépendance du module dans le fichier go.mod.

module demoproject

go 1.13

require (
    golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa // indirect
    golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 // indirect
    golang.org/x/text v0.3.2 // indirect
    google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150 // indirect
    google.golang.org/grpc v1.26.0 // indirect
)

https://blog.golang.org/using-go-modules

28voto

Mad Wombat Points 1133

J'ai un problème similaire et la solution que j'utilise actuellement utilise des modules Go 1.11. J'ai la structure suivante

- projects
  - go.mod
  - go.sum
  - project1
    - main.go
  - project2
    - main.go
  - package1
    - lib.go
  - package2
    - lib.go

Et je suis capable d'importer le package1 et le package2 du projet1 et du projet2 en utilisant

import (
    "projects/package1"
    "projects/package2"
)

Après avoir exécuté go mod init projects . Je peux utiliser go build à partir des répertoires projet1 et projet2 ou je peux faire go build -o project1/exe project1/*.go à partir du répertoire des projets.

L'inconvénient de cette méthode est que tous vos projets finissent par partager la même liste de dépendances dans go.mod. Je suis toujours à la recherche d'une solution à ce problème, mais il semble qu'elle puisse être fondamentale.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X