Goでローカルパッケージをインポートする方法は?


100

ローカライズしたいサンプルコードを作成するのは初めてです。

元のmain.goインポートステートメントでは、次のようになりました。

 import (
    "log"
    "net/http"
    "github.com/foo/bar/myapp/common"
    "github.com/foo/bar/myapp/routers"
)

今私は持っていてcommonroutersパッケージします/home/me/go/src/myapp

そこで、importステートメントを次のように変換しました。

import (
    "log"
    "net/http"
    "./common"
    "./routers"
)

しかし、実行するgo install myappと、次のエラーが発生します。

can't load package: /home/me/go/src/myapp/main.go:7:3: local import "./common" in non-local package

また、importステートメントでcommonandのrouters代わりに./commonandを使用すると./routers、次のようになります。

myapp/main.go:7:3: cannot find package "common" in any of:
    /usr/local/go/src/common (from $GOROOT)
    /home/me/go/src/common (from $GOPATH)
myapp/main.go:8:2: cannot find package "routers" in any of:
    /usr/local/go/src/routers (from $GOROOT)
    /home/me/go/src/routers (from $GOPATH)

どうすればこれを修正できますか?


5
インポートパスに関係なく、すべてのインポートは「ローカル」です。詳細な説明については、「Goコードの書き方」を参照してください。
JimB 2016

24
@JimBは哲学的な議論はさておき、私が懸念しているのは、上記の問題をどのように解決するかです。
Karlom 2016

3
私は哲学的な声明を出そうとはしていません。文字通り、すべてのインポートはローカルファイルシステムで行われると言っています。それらがリモートリポジトリから発信されているかどうかに違いはありません。相対パスを使用しようとしないでください(それらは時々機能しますが、推奨されません)。「Goコードの書き方」ドキュメント、特に「コード編成」のセクションに目を通します。
JimB 2016

回答:


69

さて、私は問題を理解しました。基本的に、インポートの開始パスは次のとおりです。$HOME/go/src

したがってmyapp、パッケージ名の前に追加する必要がありました。つまり、インポートは次のようになります。

import (
    "log"
    "net/http"
    "myapp/common"
    "myapp/routers"
)

3
のようなプロジェクト名を使用myappすることは悪い考えです。たとえば、プロジェクト名を変更すると、すべてのインポートが失敗します
TomSawyer 2018年

8
代替手段は何ですか?Goは、相対インポートを使用することをお勧めしません。
サムホームズ

12
もちろん、プロジェクト名を変更すると、すべてのインポートが失敗します。プロジェクト名はめったに変更されません。
ダミアンロシュ

23
さて、go1.11の時点で、新しいモジュールシステムを使用できます。go mod init <module_name>そしてちょうどimport "<module_name>/<pkg_name>"
shriek 2018年

github.com/dgrijalva/jwt-goを.goファイルにインポートするにはどうすればよいですか?私のJWT-、外出先フォルダはSRC / github.com / dgrijalvaの内側にある
マニクタクール

34

上記のGo1.5を使用している場合は、ベンダー機能の使用を試みることができます。これにより、ローカルパッケージをベンダーフォルダーの下に置き、より短いパスでインポートできます。あなたの場合、あなたはあなたの共通ルーターフォルダをベンダーフォルダの中に置くことができます

myapp/
--vendor/
----common/
----routers/
------middleware/
--main.go

このようにインポートします

import (
    "common"
    "routers"
    "routers/middleware"
)

Goは、$ GOPATH / srcではなくプロジェクトのベンダーディレクトリ(少なくとも1つの.goファイルがある場合)からパッケージを検索しようとするため、これは機能します。

参考:この機能を使用すると、パッケージの「すべての依存関係のコード」を独自のプロジェクトのディレクトリ内に配置できるため、ベンダーでさらに多くのことができるため、すべてのビルドで常に同じ依存関係のバージョンを取得できます。Pythonのnpmやpipに似ていますが、依存関係をプロジェクトに手動でコピーする必要があります。簡単にしたい場合は、DanielTheophanesによる政府を探してみてください。

この機能の詳細については、こちらをご覧ください

DanielTheophanesによるベンダーフォルダの理解と使用

Lucas Fernandes daCostaによるGo依存関係管理の理解

あなたや他の誰かがそれを助けてくれることを願っています


19

インポートパスは、ユーザー変数$GOPATH$GOROOT環境変数に関連しています。たとえば、次のようになります$GOPATH

GOPATH=/home/me/go

とにあるパッケージは/home/me/go/src/lib/common/home/me/go/src/lib/routersそれぞれ次のようにインポートされます。

import (
    "lib/common"
    "lib/routers"
)

はい、最初の例は私の間違いでした。
wlredeye 2016

ツールでサポートされていない相対パスとはどういう意味ですか?
wlredeye 2016

2
go install相対インポートを使用するパッケージはできません。
JimB 2016

ここでの誤解だと思います。私はGOPATHに関連することを意味します。「../../mypackage」のような相対的なものだけではありません
wlredeye 2016

これは、現在のディレクトリを基準にしてインポートについて修正した部分を参照しています。はい、すべてのユーザーインポートはに関連してい$GOPATH/srcます。
JimB 2016

5

ローカルパッケージは、外出先で厄介な問題です。

当社の一部のプロジェクトでは、サブパッケージをまったく使用しないことにしました。

  • $ glide install
  • $ go get
  • $ go install

すべての仕事。

一部のプロジェクトでは、サブパッケージを使用し、フルパスでローカルパッケージをインポートします。

import "xxxx.gitlab.xx/xxgroup/xxproject/xxsubpackage

ただし、このプロジェクトをフォークした場合でも、サブパッケージは元のプロジェクトを参照します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.