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

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

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

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

Q&A

解決済

1回答

1258閲覧

【GO】Go Modulesでローカルパッケージのインポートができない。

HHHXXX

総合スコア1

Go

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

0グッド

1クリップ

投稿2023/09/05 14:15

編集2023/09/06 01:51

実現したいこと

Go Modulesでのローカルパッケージのインポート

  • 別ディレクトリにあるローカルのパッケージのインポート

前提

GO言語の勉強をしており、書籍にはGOPATHでのローカルパッケージのインポートを行っていましたが、調べてみるとGo Modulesを使ってインポートが出来るようなので、そちらでインポートしたいです。

ファイル構成:(わかりにくくてすみません!)
pkg
ーーー>hello
ーーーーーー>hello.go
ーーーーーー>go.mod

src
ーーー>main.go
ーーー>go.mod

pkg/hello/go.mod

module hello go 1.20 replace( learning.com/hello => [絶対パス]\GO\pkg\hello )

src/go.mod

module src go 1.20

src/main.go(importの部分)

GO

1import ( 2 "fmt" 3 "hello" 4)

行ったこと:

  1. hello.go、main.goを作成
  2. それぞれのgo.modを作成
  3. pkg/hello/go.modにreplace文を追加
  4. src/にてgo build実行(失敗)
  5. go get learning.com/hello実行(失敗)

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

go buildを行うと、

no required module provides package learning.com/hello; to add it: go get learning.com/hello

なので go get learning.com/helloを行ったが、

unrecognized import path "learning.com/hello": reading https://learning.com/hello?go-get=1: 404 Not Found

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

GO version:1.20.7
書籍

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

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

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

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

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

ikedas

2023/09/06 01:39

参考にした書籍の情報 (著者、タイトル、出版社、ページ) を記してください。 このコメント欄に書くのではありません。質問文を編集して書き加えてください。
HHHXXX

2023/09/06 01:53

今回の質問にその情報は不必要、また書籍のコードは載せてはいけないだろうと思って諸々省いたのですが、このようなコメントをされた意図を知りたいです。
ikedas

2023/09/06 02:21

回答する側にとっては必要です。参考にした書籍にもともと書いてあったコードや説明はどんなもので、質問者さんの考えで書いたのがどこなのかがわからないと、回答を考えられないです。 つまり、質問中で「この本には○○と書いてあった」ということをぼかしたり省略したりするのではなく、きちんと原文通りに**引用**してもらわないと、著者の書いたことを正しくとらえられないです。 ちなみに、著作物の引用は、正当な範囲内でなら許可なくできます (下記参照)。つまり、「この本には○○と書いてありましたが、それを参考に私は○○と考えてみました。どうでしょうか?」といったことを書くのは自由です。 https://www.bunka.go.jp/seisaku/chosakuken/seidokaisetsu/gaiyo/chosakubutsu_jiyu.html もちろん正当な範囲内なので、今回の質問に関係ない箇所まで書き写すとかいうのはだめなのは当然です。
HHHXXX

2023/09/06 02:27

今回だとどこの部分が理解に苦しむ部分でしたか?それに合わせて追記させていただきます。
HHHXXX

2023/09/06 02:28

今回の質問に回答できない要因をお教えいただきたいです。
ikedas

2023/09/06 02:54

> 書籍にはGOPATHでのローカルパッケージのインポートを行っていましたが、 の場合のgo.modはどんな内容だったのでしょうか。引用して示してください。
ikedas

2023/09/06 02:57

また、書籍ではsrc/go.modとpkg/hello/go.modの両方があったのでしょうか。書籍ではなかったが自分で付け足したものもあるのでしょうか。
HHHXXX

2023/09/06 07:44

全て読み切ったわけではないので断定はできないですが、go.modについての記述は一切ありませんでした。
ikedas

2023/09/06 08:04

なるほど。書籍ではワークスペースモードのみ解説していたのですね。 上のうち、Zennの記事はGoのバージョンがちょっと古いですね。 あと、Qiitaの記事は、サブパッケージを使えばいいのにわざわざgo.modを用意しているために複雑なことをしています。これについてはこちらの記事もご覧ください。 https://zenn.dev/nobonobo/articles/1d4afb9f4e8873 しかし、HHHXXXさんの環境でgo getが実行できたというのがちょっと不思議ですね。go versionを実行した結果はどうなりますか。
HHHXXX

2023/09/06 10:24

1.20.7です
ikedas

2023/09/07 02:03

本当だ。仮のgo.modを作って実行したら同じエラーメッセージが出ました。モジュール内**以外**でのgo getは廃用ということですね。回答訂正しておきます。 いろいろと細かいことをお尋ねしましたが、同じような問題にぶつかったひとがこの質問と回答を見て参考にしてもらえるようにするためです。私自身は普段、仕事としてこの種の質問をお客様から受けて回答することもあるのですが、質問したひとだけのために回答するのなら無料ではやらないですもんね。 また質問してください (私が回答するとはかぎりませんが)。
HHHXXX

2023/09/07 04:04

他社への配慮、意識が薄かったです。勉強になりました、ありがとうございます。
guest

回答1

0

ベストアンサー

GOPATHによるワークスペースモードを使わないのであれば、srcpkgbinというサブディレクトリは必要ありません。

また、モジュール名を見る限りhelloは公開モジュールとして使ってもらうことを想定していないのではないかとも思えます (learning.comというのが何なのかはわかりませんでした)。その場合は独立したgo.modを書く必要はありません。

次のようなディレクトリ構成にすれば、helloパッケージがprojectモジュールのサブパッケージとなり、project/helloとしてインポートできます。replace行によってリモートパスをローカルパスに置き換えたりする必要はありません。

project/ +- go.mod +- main.go +- hello/ +- hello.go

コードはこのようになります。

go.mod

module project go 1.20

main.go

package main import "project/hello" ...

hello/hello.go

package hello ...

公開モジュールにする場合

一方、helloを公開モジュールにしたいのであれば、モジュール固有のgo.modを作成する必要があります。

また、module行にはリモートパスを書く必要があります (当然、そのリモートパスの場所にモジュールを置いておく必要があります。実際にどうやるかは別途調べてください)。

また、ローカルパスにあるモジュールをインポートしたい場合は、リモートパスをローカルパスに置き換えます。なお、置き換えをするのはモジュールをインポートする側ですから、プロジェクトのgo.modreplace行を記述します。

以下、モジュールが https://github.com/none/hello という場所に存在するという前提で説明します。

helloモジュールのgo.mod (作成)

module github.com/none/hello go 1.20

上記のモジュールを使うプロジェクトのコードは以下のようになります。

go.mod

module project require github.com/none/hello vX.X.X go 1.20

require行はgo mod tidyを実行すれば自動的に追加されます。

また、ローカルパスにあるhelloモジュールを使いたければ、次のようなreplace行を追加します (ちなみに相対パスも書けるはずです)。

replace github.com/none/hello => ローカルのhelloへのパス

main.go

package main import "github.com/none/hello" ...

余談

質問者さんが参考になさった書籍はGo 1.15.1を前提にしているとのことです。

たとえば、go getのモジュール外での使用はGo 1.17で非推奨となり、Go 1.18で廃用となっています。つまり質問者さんの使っているGo 1.20.7では従来の使用方法で使えない場合があります (その場合には「インストールにはgo installを使え」といったエラーメッセージが出ます)。

Goはここ数年でかなり変化がありましたから、書籍やウェブの記事などを参考にするときは公式サイトなどの最新の情報と照らし合わせるようにするとよいです。

投稿2023/09/06 03:53

編集2023/09/07 02:23
ikedas

総合スコア4443

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問