Go初心者の自分が躓いたのでメモ
Go速習会という記事を参考に自分自身で実行していた所躓いた.
本題
たとえば,goのnegroniというWAFでwebアプリケーションを作成しようとしていたとする.
ツリー構造は以下の通り.
.
├── models
│ └── user.go
├── public
│ └── index.html
└── server.go
各ファイルは以下の通り
package main
import (
"fmt"
"github.com/codegangsta/negroni"
"github.com/[username]/[appname]/models" // 自分のパッケージ
"net/http"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
user := models.NewUser("Tanaka Tarou", 10)
fmt.Fprintln(w, user)
})
n := negroni.Classic()
n.UseHandler(mux)
n.Run(":8080")
}
package models
import "strconv"
// User defines an user
type User struct {
ID int
Name string
Age int
}
// NewUser creates user instance
func NewUser(name string, age int) *User {
return &User{
Name: name,
Age: age,
}
}
func (u *User) String() string {
return u.Name + "(" + strconv.Itoa(u.Age) + ")"
}
server.go
というファイルがメインになっており,
モデルとして定義したmodels/user.go
の NewUser関数をmain関数で利用する時,
import (
"fmt"
"github.com/codegangsta/negroni"
"github.com/[username]/[appname]/models" // 自分のパッケージ
"net/http"
)
このようにして,自分自身のモデルを定義しなければならない.
特に意識せずに,このまま実行すると…
$ go run server.go
server.go:6:2: cannot find package "github.com/[username]/[appname]/models" in any of:
/usr/local/opt/go/libexec/src/github.com/[username]/[appname]/models (from $GOROOT)
/Users/[username]/src/github.com/[username]/[appname]/models (from $GOPATH)
このようにしてエラーが起きる.
その1(推奨)
@1l0さんより推奨していただいた方法です.
$GOPATH/src/github.com/[username]/[appname]
この中で最初から作業をしてしまう.
つまり,今回の場合では,
/Users/[username]/src/github.com/[username]/[appname]
という場所を作り,はじめからそのdir配下で作業をすれば良い事になる.
github.com
└── [username]
└── [appname]
├── models
│ └── user.go
├── public
│ └── index.html
└── server.go
これで最初から$ go get
などせずに済む.
その2
githubにpushする.
$ git init
$ git add .
$ git commit -m "update model"
$ git remote add origin [githubのリポジトリ]
$ git push origin master
次に,githubへのpushが完了した事を確認してから,
$ go get github.com/[username]/[appname]/models
を実行し,再び$ go run server.go
をすると上手くいく.
その3(非推奨)
相対パスでpackageを指定する方法.
Go言語でローカルパッケージをインポートという方法があるらしい.
しかし,一般的にはオススメされている方法では無いそうです.
以下は,@1l0さんのコメントより引用です.
相対パスは以下の理由でお勧めしません。
- 毎度pkg化することになるのでコンパイルが遅い
- 他人が普通にgo getできない