web-dev-qa-db-ja.com

親ディレクトリからの相対的なインポート

親ディレクトリからの相対的なインポートはどのように行いますか?

meme/cmd/memeから:

import "../../../meme"

これによりあいまいなエラーが発生します。

matt@stanley:~/gopath/src/bitbucket.org/anacrolix/meme/cmd/meme$ go get bitbucket.org/anacrolix/meme/cmd/meme

can't load package: /home/matt/gopath/src/bitbucket.org/anacrolix/meme/cmd/meme/main.go:8:2: local import "../../../meme" in non-local package

matt@stanley:~/gopath/src/bitbucket.org/anacrolix/meme/cmd/meme$ echo $GOPATH

/home/matt/gopath

親ディレクトリからローカルにインポートするにはどうすればよいですか?

41
Matt Joiner

質問を追加していただきありがとうございます。最初に答え、次に説明。コードを作成しました、

  1. あなたがそれを持っていたように、取得してください。 (エラーメッセージは無視しました。)
  2. 必要に応じて、main.goのインポート行を "../../../meme"に戻します。
  3. (未使用の変数を含む少しのコードをコメントアウトします。)
  4. その後、meme/cmd/memeディレクトリで、go run main.goまたはgo build main.goが機能しました。

先に行ったインストールの動作を言ったとき、私は私のコメントで間違っていました。ビルドに行くと言ったはずです。

ただし、重要なのは、go buildだけでは機能しないことです。 go build main.goと入力する必要があります。これは、goコマンドが「非ローカルパッケージでのローカルインポート」を許可しないためです。この仕様はここではほとんど役に立たないというのは正しいことです。 「ImportPathの解釈は実装に依存します。」現在の実装動作は CL 5787055 で設定され、その後、ゴーナットで 詳細に議論されました になりました。

「ローカル」は、ファイルシステムの相対パスで示されることを意味します。明らかに..で始まる相対パスはローカルなので、トリックはgoコマンドを取得してmainをローカルパッケージとしても処理することです。 go buildと入力したときは明らかにこれを行いませんが、go build main.goと入力したときはこれを行います。

17
Sonia

編集:相対インポートパスはGoに行く方法ではありません。ドキュメントの欠如は相対パスの人気について何かを示しており、それらを使用する理由はわかりません。 Goが推奨するコード編成は非常にうまく機能します。すべてのパッケージには一意のインポートパスがあり、同じインポートパスを使用してどこでもインポートする必要があります

github.com/ha/doozerd/peer近隣をインポートする のようなパッケージをご覧ください。これはGoプロジェクトで一般的な方法であり、何度も見ています。パッケージ camlistore.org/pkg/auth (同様に GitHub ; Goの主要著者の1人によって書かれました)は、camlistore.org/pkg/netutilをフルパスでインポートします。

同じプロジェクトにコマンドとライブラリの両方がある場合でも、このアプローチは機能します。最初の質問では、ベストプラクティスを賢く尋ねました。この問題のベストプラクティスを説明するために最善を尽くしました。


Goではインポートパスを相対パスにすることはできません。 Goコードの書き方 を読むことをお勧めします。これはGoプロジェクトの整理に関する重要な読み物です。以下に簡単な概要を示します。

Go開発用に~/goのようなディレクトリを作成します。次に言う:

$ export GOPATH=~/go
$ mkdir $GOPATH/{src,bin,pkg}

$GOPATH/srcは、go getを使用してダウンロードしたものも含め、すべてのGoパッケージのソースコードを保持します。 binおよびpkgは、コンパイルの出力を保持します。パッケージ名がmainのパッケージはコマンドであり、$GOPATH/binに移動する実行可能バイナリになります。他のパッケージはライブラリであり、コンパイルされたオブジェクトファイルは$GOPATH/pkgに置かれます。

コードを$GOPATH/src/matt/memeに配置すると、import "matt/meme"でインポートできます。パッケージ名にはプレフィックスを使用し、標準ライブラリには短いパッケージ名を残すことをお勧めします。だから$GOPATH/src/matt/memeの代わりに$GOPATH/src/memeを使用しました。

このアイデアを中心にコードを整理します。

48
Mostafa

コンパイラ、リンカーなどを直接手動で使用する場合、相対インポートがサポートされます。 'go'(ビルド)ツールは同じものをサポートしていません(たとえばJavaに匹敵します)。

3
zzzz