質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

import

自身のプラットフォーム・プログラム・データセットに対して、外部ソースを取り込むプロセスをimportと呼びます。

Q&A

解決済

1回答

2507閲覧

自作パッケージをメインパッケージにインポートできない

noa-1129

総合スコア25

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

import

自身のプラットフォーム・プログラム・データセットに対して、外部ソースを取り込むプロセスをimportと呼びます。

0グッド

1クリップ

投稿2022/05/23 02:53

編集2022/05/24 15:12

前提

スターティングGo言語技術本を参考に簡単な自作パッケージをメインパッケージにインポートしようとしたところエラーが出ました。

発生している問題・エラーメッセージ

could not import fmt (cannot find package "fmt" in any of /Users/noay/.goenv/versions/1.15.2/src/fmt (from $GOROOT) /Users/noay/go/1.15.2/src/fmt (from $GOPATH))compiler
could not import ./animals (cannot find package "./animals" in any of /Users/noay/.goenv/versions/1.15.2/src/animals (from $GOROOT) /Users/noay/go/1.15.2/src/animals (from $GOPATH))compiler

該当のソースコード

main.go

1package main 2 3import ( 4 "fmt" 5 6 "./animals" 7) 8 9func main() { 10 fmt.Println(animals.ElephantFeed()) 11 fmt.Println(animals.MonkeyFeed()) 12 fmt.Println(animals.EabbitFeed()) 13}

animals/elephant.go

1package animals 2 3func ElephantFeed() string { 4 return "Grass" 5}

animals/monkey.go

1package animals 2 3func MonkeyFeed() string { 4 return "Banana" 5} 6

rabbit.go

1package animals 2 3func RabbitFeed() string { 4 return "Carrot" 5}

補足情報(FW/ツールのバージョンなど)

go version go1.15.2 darwin/amd64

$GOPATH=~/go/1.15.2

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

GOPATHはGoのインストール先を指定するものではありません。
外部ライブラリのキャッシュや外部実行ファイルのインストール先として利用する親フォルダを指定します。
あらゆる環境変数設定はドキュメントを読まないのであれば何も設定しないほうが良いと思います。

以下追記

Go向けの「ほげenv」の類の利用はお勧めしません。Go単体でGoのバージョン別ツールチェインのインストール機能があるのでそちらを使えば大丈夫。
また、「Goモジュールモード」という新しい仕組みを利用することで、Goのバージョン別にGOPATHを用意する必要はなくなりました。
(これがさらに「ほげenv」が不要な理由です)

「Goモジュールモード」以前のモードは「GOPATHモード」と呼んで区別されていますが、
「GOPATHモード」では複数パッケージを扱うプロジェクトはGOPATH配下に置く必要がありました。
(Go1.15ではGOPATH配下ならGOPATHモード、そうでないならGoモジュールモードとして動作しようとします)
「Goモジュールモード」にてその制約は無くなりました。Go1.16からはデフォルトでGoモジュールモードとして動作します。
(なので、Go1.16以降を使うとエラーメッセージが変化すると思います)
「Goモジュールモード」では任意のフォルダをGoモジュールとして初期化することでプロジェクトフォルダとして扱えるようになります。
特別にGOPATHモードでなければビルドできないなどの理由がない限りGoモジュールモードを使うことを推奨します。

Goモジュールモードの基本

shell

1mkdir zoo 2cd zoo # ここをプロジェクトフォルダにしたいときに以下のコマンドを実行します 3go mod init github.com/username/zoo

go mod init に与える名前はユニークな名前を付与すればOKですが、以上のようにリポジトリURLになっていることが推奨です。(スラッシュ区切りがある場合最初の要素には必ず途中にドットが必要です。リポジトリに公開するつもりがないなら単発の名前例えば「zoo」だけでもいいです。)
実際に存在するリポジトリがかどうかはこの時点では関係ありませんが、作ったモジュールをgo-get可能にするためには実在のリポジトリと名前を合致させる必要があります。

この際、go.modファイルが作られますが、
その中身は以下のようになります。

module github.com/username/zoo go 1.1?

さらにサブフォルダ「animals」を作成し、その下にパッケージ実装を作成した場合、その「animals」のインポート方法は以下のように書きます。

go

1import "github.com/username/zoo/animals"

つまり、go.mod先頭行に書かれた「モジュール名」をプレフィックスにしてパスをフルパスに組み立ててインポートパスとします。

投稿2022/05/23 04:00

編集2022/05/23 06:09
nobonobo

総合スコア3367

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

noa-1129

2022/05/23 04:30

デフォルトだとGOPATH=~/goとのことなのですが知識なく設定してしまったためGOPATHがよくわからないところに指定されてしまっていました💦今のGOPATH配下にはすでにpkg、bin、srcディレクトリが作成されています。go env -w GOPATH=でデフォルトに変更ができるのであれば正常に動くようになるのでしょうか?その後のアプローチに迷ってしまっていますご教授いただきたいです、
nobonobo

2022/05/23 05:37

あ、今気づきましたが、goenvが設定するGOPATHですね。 goenvはお勧めしません。エディタ連携などでおそらくより苦労すると思います。 また、Go1.15はもうサポートされないバージョンですので、可能であればGoの1.17以降をお使いください。 さらに、インポートで「./animals」のように相対パスインポートはもともと非推奨かつ 現在主流の「Goモジュールモード」ではエラー扱いになりました。 相対インポートの利用はデメリットばかりになるし、メリットもほぼないと思います。 以上いろいろと問題のある状態なのと、特にGo1.15.2に用事があるのでなければですが、 今ある、GOPATHや.goenvフォルダはきれいさっぱり消してしまって、 最新もGoを公式が勧める方法でインストールするのをお勧めします。 macOSかつHomebrewをお使いなら「brew install go」でよいかと思います。 あとはPATH環境変数に「$(go env GOPATH)/bin」を加えておきましょう。 相対パスをなくす方法は後で追記します。
noa-1129

2022/05/24 02:33

長々とご説明ありがとうございます!フローは理解しました。そこでgo mod init コマンドですが、go: cannot find GOROOT directory: /Users/noay/.goenv/versions/1.15.2というエラーが出ました。GOPATと.goenvはrmしたのですが、前バージョンを引きずってしまっています。zshへのGOROOTに問題があるように思ったのですが、変更の必要な点は見受けられますでしょうか? .zshrc export GOPATH=$HOME/go export PATH=$GOPATH/bin:$PATH export GOENV_ROOT=$HOME/.goenv export PATH=$GOENV_ROOT/bin:$PATH eval "$(goenv init -)" .zshenv_profile export GOPATH=$HOME/go export GOENV_ROOT=$HOME/.goenv export PATH="$GOENV_ROOT/bin:$PATH" eval "$(goenv init -)" export PATH=$PATH:$GOPATH/bin
nobonobo

2022/05/24 04:25

双方のスクリプトから以下の該当行は消してしまいましょう! export GOENV_ROOT=$HOME/.goenv export PATH=$GOENV_ROOT/bin:$PATH eval "$(goenv init -)"
noa-1129

2022/05/24 06:12

リロードが遅れたためご回答の表示に遅れてしまい重ね重ねに送ってしまいました。問題なく解決いたしましたありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問