Goビルド:「パッケージが見つかりません」(GOPATHが設定されている場合でも)


139

GOPATH適切に設定したにもかかわらず、自分のパッケージを見つけるために「ビルド」または「実行」することができません。何が悪いのですか?

$ echo $GOROOT
/usr/local/go

$ echo $GOPATH
/home/mitchell/go

$ cat ~/main.go
package main
import "foobar"
func main() { }

$ cat /home/mitchell/go/src/foobar.go
package foobar

$ go build main.go
main.go:3:8: import "foobar": cannot find package

github.com/adonovan/gopl.io/tree/master/ch1/helloworldを取得すると、同じ問題が発生します 。理由は、helloworld.goという名前のファイルがないためです。パッケージ名とファイル名を一致させることで機能します。
keniee van

Goをアップグレードする必要がある場合もあります。モジュールを定義するためにgo.modを使用している既存のコードがあるという同様の問題がありました。テストマシンでコードをダウンロードしてコンパイルしようとしていましたが、GoはGOPATHに関連するあらゆる種類のエラーを出し、モジュールを見つけることができませんでした。Goバージョン1.7でした。Goをアップグレードするとすぐに、問題なく動作しました。
KyferEz

これを入力すると、最新の説明が表示されます$ go help gopath
A1rPun

回答:


162

foobar.goソースファイルがというディレクトリにないため、機能しませんfoobargo buildそしてgo install、ソースファイルではなく、ディレクトリを一致させようとします。

  1. $GOPATH有効なディレクトリに設定してください。export GOPATH="$HOME/go"
  2. に移動foobar.go$GOPATH/src/foobar/foobar.go、建物はうまく動作するはずです。

追加の推奨手順:

  1. 追加$GOPATH/binあなたに$PATHすることにより:PATH="$GOPATH/bin:$PATH"
  2. main.goサブフォルダに移動します$GOPATH/src。例:$GOPATH/src/test
  3. go install testこれで、端末に$GOPATH/bin入力testして呼び出すことができる実行可能ファイルが作成されます。

1
これはバグではありませんか?My GOPATH=/usr/local/go-pkgsなので、Goは/usr/local/go-pkgs/src/<package-name>ソースを探しますが、にgo get入れ/usr/local/go-pkgs/src/gopkg.in/<package-name>ます。インストール後にすべてのパッケージを手動で移動する必要があるのはなぜですか?それはばかげています。
ジョサイア

3
go get通常はパッケージを入れる$GOPATH/src/ので、呼び出すgo get domain.com/path/to/packageと最終的にはになり$GOPATH/src/domain.com/path/to/packageます。からパッケージを取得しようとしていると思いますgopkg.inか?もしそうなら、それは絶対的に意図された動作であり、あなたはそれらを完全な名前でインポートするべきです。たとえば、ドキュメントにimport "gopkg.in/yaml.v1"記載されています。
fasmat

1
ああ、なるほど。私の無知を払拭してくれてありがとう。
ジョサイア2015

10

編集:GOPATHを意味しているため、fasmat回答を参照(賛成)

パッケージを見つけるにはどうすればよいですか?」で説明したように、パッケージxxxをディレクトリに配置する必要がありますxxx

Go言語仕様をご覧ください。

package math

PackageNameパッケージの実装を同じ形式で共有するファイルのセット。
実装によっては、パッケージのすべてのソースファイルが同じディレクトリに存在する必要がある場合があります。

コードの組織は言及します:

パッケージをインポートするプログラムをビルドするとき」widget "、goコマンドはsrc/pkg/widgetGoルートsrc/widget内を探し、そこにパッケージソースが見つからない場合は、各ワークスペース内を順番に検索します。

(「ワークスペース」はあなたのパスエントリですGOPATH:その変数はあなたの ' src, bin, pkg'になるための複数のパスを参照できます)


(元の答え)

また、「」GOPATHではなくGOROOT、〜/ goに設定する必要があります。 Goコードの書き方ます。

Goパスは、インポートステートメントを解決するために使用されます。go / buildパッケージによって実装され、ドキュメント化されています。

GOPATH環境変数リストのGoコードを探すための場所。
Unixでは、値はコロンで区切られた文字列です。
Windowsでは、値はセミコロンで区切られた文字列です。
プラン9では、値はリストです。

それはとは異なりGOROOTます:

Goバイナリディストリビューションは、/usr/local/go(またはc:\GoWindowsで)インストールされることを前提としていますが、別の場所にインストールすることもできます。
これを行う場合GOROOT、Goツールを使用するときに、環境変数をそのディレクトリに設定する必要があります。


4
GOPATHのセットアップに関する短いビデオイントロもあります
Ulf Holm Nielsen

1
元の質問を編集しました。私がGOROOTと言ったところはどこでも、GOPATHを意味しました。
MitchellSalad

3

TL; DR: Goの規則に従ってください!(レッスンは難しい方法を学びました)、古いgoバージョンをチェックして削除します。最新をインストールします。

私にとって、解決策は異なっていました。私は共有Linuxサーバーで作業しましたが、自分GOPATHや他の環境変数を数回確認した後も機能しませんでした。「パッケージが見つかりません」や「認識できないインポートパス」など、いくつかのエラーが発生しました。golang.orgアンインストール部分を含む)の指示に従ってこのソリューションで再インストールしようとした後も、問題が発生しました。

アンインストールされていない古いバージョン(ランニングまだありますことを実現するために私にいくつかの時間がかかったgo version後、which go再び... DAHH)に私を得た、この質問し、最終的に解決が。


2

受け入れられた答えは、ディレクトリをパッケージ名と照合する必要があることについては依然として正しいですが、GOPATHを使用する代わりにGoモジュールを使用するように移行する必要があります。この問題に遭遇した新しいユーザーは、GOPATHの使用について(私がそうであったように)言及していることに混乱しているかもしれません。そこで、この問題を解決し、Goモジュールを使用する場合のこの問題の防止に関連するガイダンスを提供するように努めます。

Goモジュールに既に精通していて、この問題が発生している場合は、見落としたり忘れたりしやすいGoの規則のいくつかをカバーする、以下のより具体的なセクションにスキップしてください。

このガイドでは、Goモジュールについて説明しています:https : //golang.org/doc/code.html

Goモジュールを使用したプロジェクト編成

Goモジュールに移行したら、その記事で説明したように、説明に従ってプロジェクトコードを編成します。

リポジトリには1つ以上のモジュールが含まれています。モジュールは、一緒にリリースされる関連するGoパッケージのコレクションです。Goリポジトリには通常、リポジトリのルートにある1つのモジュールのみが含まれています。そこでgo.modという名前のファイルでモジュールパスを宣言します。これは、モジュール内のすべてのパッケージのインポートパスプレフィックスです。モジュールには、go.modファイルを含むディレクトリ内のパッケージと、そのディレクトリのサブディレクトリが含まれ、次のサブディレクトリまで、別のgo.modファイル(存在する場合)が含まれます。

各モジュールのパスは、パッケージのインポートパスプレフィックスとして機能するだけでなく、ダウンロードするためにgoコマンドがどこを探すべきかを示します。たとえば、モジュールgolang.org/x/toolsをダウンロードするために、goコマンドはhttps://golang.org/x/toolsで示されるリポジトリを参照します(詳細はこちら)。

インポートパスは、パッケージのインポートに使用される文字列です。パッケージのインポートパスは、モジュール内のサブディレクトリと結合されたモジュールパスです。たとえば、モジュールgithub.com/google/go-cmpには、ディレクトリcmp /にパッケージが含まれています。そのパッケージのインポートパスはgithub.com/google/go-cmp/cmpです。標準ライブラリのパッケージには、モジュールパスのプレフィックスがありません。

次のようにモジュールを初期化できます:

$ go mod init github.com/mitchell/foo-app

ビルドするためにコードをgithub.comに置く必要はありません。ただし、最終的には公開されるようにモジュールを構成することがベストプラクティスです。

パッケージを取得しようとするとどうなるかを理解する

パッケージまたはモジュールを取得しようとするとどうなるかを説明したすばらしい記事があります。https//medium.com/rungo/anatomy-of-modules-in-go-c8274d215c16 パッケージの保存場所とGoモジュールを既に使用している場合に、このエラーが発生する理由を理解するのに役立ちます。

インポートされた関数がエクスポートされたことを確認します

別のファイルから関数にアクセスできない場合は、関数をエクスポートしたことを確認する必要があります。私が提供した最初のリンクで説明したように、関数は大文字で始まり、エクスポートして他のパッケージにインポートできるようにする必要があります。

ディレクトリの名前

(受け入れられた回答で述べられているように)もう1つの重要な詳細は、ディレクトリの名前がパッケージの名前を定義するものであるということです。(あなたのパッケージ名は、そのディレクトリ名と一致する必要があります。)あなたはここで、この例を見ることができます:https://medium.com/rungo/everything-you-need-to-know-about-packages-in-go-b8bac62b74cc 付きmainつまり、メソッド(つまり、アプリケーションのエントリポイント)を含むファイルは、この要件からある程度除外されています。

例として、次のような構造を使用すると、インポートで問題が発生しました。

/my-app
├── go.mod
├── /src
   ├── main.go
   └── /utils
      └── utils.go

私は、内のコードをインポートすることができませんでしたutils私にmainパッケージ。

ただし、main.go以下に示すように独自のサブディレクトリに配置すると、インポートは正常に機能しました。

/my-app
├── go.mod
├── /src
   ├── /app
   |  └── main.go
   └── /utils
      └── utils.go

その例では、私のgo.modファイルは次のようになります。

module git.mydomain.com/path/to/repo/my-app

go 1.14

への参照を追加した後でmain.goを保存したときutils.MyFunction()、私のIDEは次のようにパッケージへの参照を自動的にプルしました。

import "git.mydomain.com/path/to/repo/my-app/src/my-app"

(私はGolang拡張機能付きのVSコードを使用しています。)

インポートパスに、パッケージへのサブディレクトリが含まれていることに注意してください。

プライベートレポの取り扱い

コードがプライベートリポジトリの一部である場合、アクセスを有効にするにはgitコマンドを実行する必要があります。そうしないと、他のエラーが発生する可能性がありますこの記事では、プライベートGithub、BitBucket、およびGitLabリポジトリに対してそれを行う方法について説明します。 repositories-dfe795068db4 この問題については、ここでも説明しています。プライベートリポジトリを「取得」する適切な方法は何ですか。


-6

goの絶対パスを「パス」に追加してみましたか?

export PATH=$PATH:/directory/to/go/

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