2012-05-21 15 views
32

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

meme/cmd/memeから

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

これは、あいまいなエラーを与える:

[email protected]:~/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 

[email protected]:~/gopath/src/bitbucket.org/anacrolix/meme/cmd/meme$ echo $GOPATH 

/home/matt/gopath 

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

+0

私はこれをいくつかの方法で試しましたが、あなたが言及したあいまいなエラーは見られませんでした。言葉があいまいであるか、メッセージ・テキストに単語があいまいであることを意味しますか?私が試した2つの方法は、GOPATH内のmeme/cmd/memeで、次にGOPATHの外でした。どちらの場合も、相対的なインポートパスが私にとってうまくいきました。何があなたのために働いていないの詳細を与えることができますか? – Sonia

+0

@Soniaあなたはgoツールを試しましたか?私は詳細を追加します。 –

+0

はい。私はあなたがmemeにパッケージを持っていて、meme/cmd/memeに実行ファイルがあると思っています。 GOPATHの場合は、実行したばかりの実行可能ファイルにインストールしてください。 GOPATHを超えている場合、私はgo tool 6gでmemeパッケージをコンパイルしてツールパックを実行しました。メインパッケージのインポートは、./../memeで.aを指すようにする必要がありましたが、それ以外の場合はツール6gを実行し、ツール6lを実行すると、パッケージにアクセスした実行可能な実行可能ファイルをビルドします。 – Sonia

答えて

16

ご質問ありがとうございます。最初に、答え、そしていくつかの説明。あなたのコードを作成しました。

  1. (私はエラーメッセージを無視しました。)
  2. main.goのインポート行を「../../../meme」に戻したいとしています。
  3. ミーム/ CMD /ミームディレクトリに次に
  4. (未使用の変数を含むコードの少しをコメントアウト)、のいずれかgo run main.goまたはgo build main.goが働きました。

私がgo installの仕事をしたときの私のコメントは間違っていました。私はビルドすると言っていたはずです。

ただし、鍵はgo buildだけでは機能しません。 「go build main.go」と入力する必要があります。これは、goコマンドで「ローカル以外のパッケージでのローカルインポート」が許可されていないためです。あなたはスペックがここでほとんど役に立たないというのは正しいです。 「ImportPathの解釈はインプリメンテーション依存です。現在の実装の振る舞いは、CL 5787055で設定されています。これは、Go-nutsでdebated at lengthです。

"ローカル"は、ファイルシステムの相対パスで示されます。明らかに..で始まる相対パスはローカルなので、ローカルパッケージと同様にmainを扱うためのコマンドがgoになっています。 go buildと入力したときには明らかに行われませんが、go build main.goと入力した場合は実行されます。

2

コンパイラ、リンカー、...を直接使用すると、リアクティブインポートがサポートされます。 'go'(ビルド)ツールは、同じものをサポートしていません(Javaと似ています)。

+1

。これは落胆した活動であることに言及してください。 – mvrak

41

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

パッケージの様子はgithub.com/ha/doozerd/peerimports its neighborsです。これはGoプロジェクトの中ではよくあることですが、私はそれを何度も見てきました。 camlistore.org/pkg/authGitHubにもあり、Goの主著者の1人が書いています)camlistore.org/pkg/netutilをフルパスでインポートします。

同じプロジェクトでコマンドとライブラリの両方を使用していても、このアプローチが有効です。元の質問では、ベストプラクティスを賢明に尋ねました。私はこの問題に関するベストプラクティスを説明することに最善を尽くしました。


インポートパスが移動中に相対することはできません。私はGOプロジェクトを構成する上での重要な読書であるHow to Write Go Codeを読むことをお勧めします。概要は次のとおりです。

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

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

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

$GOPATH/src/matt/memeにコードを入力すると、import "matt/meme"でコードをインポートできます。パッケージ名の接頭辞を使用し、標準ライブラリの短いパッケージ名を残すことをお勧めします。だから私は$GOPATH/src/memeの代わりに$GOPATH/src/matt/memeを使ったのです。

このアイデアの周りにコードを整理してください。

+1

私は彼らがMostafaを信じることができると信じていますが、それは文書化されていません。 –

+0

@MattJoinerあなたが正しいです。私はGoツールでそれらが可能であることを知らなかった。しかし、とにかく私はそれらを使うべきだとは思わない。私の答えを更新する必要があります。 – Mostafa

+11

相対パスは、フォークされたリポジトリを扱う1つの(IMOクリティカル)ユースケースに適しています。誰かのリポジトリをgithubにフォークすると、あなたのコピーを参照するようにすべてのインポート文を更新し、それらをアップストリームにプッシュしないことを覚えておいてください(またはアップストリームでマージでそれらを除外することを忘れないでください)。ちょうどうんざりします。 –

関連する問題