golangのお勉強16+goa


glide

glideのベンダリングはyamlで管理されている。
該当のパッケージがgopathにすでに存在する場合にも、
yaml管理には記述されるし、vendorにも取得される。

ローカルのimport

ローカルのディレクトリのimportをしてみた。(作法的にどうか。。)
Cannot detect VCSのエラーがでてうまく動かない。
途中でパッケージの取得が止まり、lockファイルは生成されなかった。
それとわかるエラーはでなかったので若干ハマりました。

ignoreに指定したらうまくいったが果たしてこれでいいのか。。
ローカルからの読み込み自体が致命傷にならないといいな。。

The glide.yaml File - Glide Documentation
https://glide.readthedocs.io/en/latest/glide.yaml/

dockerでサーバーを起動していろいろ

  • ポートのマッピングをして、ローカルからクライアントを実行
    • gulp+requestモジュール
  • サーバーで監視してサーバーとクライアント処理を実行
    • godoのstartとrun
    • macではうまく監視できなかった

型など

型とポインタを分かりやすく解説。値型と参照型についても解説しています。 - nasust blog
http://nasust.hatenablog.com/entry/2016/12/21/193455

  • 数値型

    • 実行環境でメモリのサイズが違って型のサイズが変わるやつもあるのね、きをつけよう
    • uintptr型
      • メモリと同じサイズの整数らしい(スターティングGO言語)
  • 型に名前がつけられる。

    • なるほど、同じ配列型でも区別して記述できるのね。便利。
  • レシーバー

    関数の名前の前に(self *Hoge)というレシーバーを書くことでメソッド群を定義することができます。

Go 言語の値レシーバとポインタレシーバ | Step by Step
https://skatsuta.github.io/2015/12/29/value-receiver-pointer-receiver/

Go 言語の値レシーバとポインタレシーバがある。
理屈や使い分けなどについて言及。
関数内でポインタと値について暗黙的に変換してくれるらしい。。

わかりやすい。。
ここでは、基本はポインタ渡ししろと、、しかし別の記事では値渡しでいいとある。。うーん。

Goでxxxのポインタを取っているプログラムはだいたい全部間違っている - Qiita
http://qiita.com/ruiu/items/e60aa707e16f8f6dccd8

gormaのモデルからgoaのメディアタイプ定義の構造体への変換

hoge_helper.goに変換の関数が用意されていた。
下記のような感じ。

res := &app.MediaUser{}
res = user.ModelUserToMediaUser()

return ctx.OK(res)

ほげ渡し、ポインタ周り

逆参照演算子とか単項間接演算子は参照演算子と同じと捉えていいものなのかどうなのか。。

j := i #値を代入
r := *i #参照演算子
p := &i
fmt.Println("p(=i)の値:", p)
fmt.Println("pの中身:", *p)

ポインタ渡しと参照渡しと値渡し

  • 値渡しは、変数の中身を、値を複製して、新しいアドレスで保持(複製物)
  • 参照渡しは、変数の中身のアドレスと値を保持(たぶん、変数という器以外は全く同一なのかな?)
  • ポインタ渡しは、元のアドレスへのリンクを保持(アドレスへのリンク)

Goのポインタ - はじめてのGo言語
http://cuto.unirita.co.jp/gostudy/post/pointer/

値渡し、ポインタ渡し、参照渡しの違い - Qiita
http://qiita.com/Rompei/items/e70e3b453cb485858062

急いで学ぶGo lang#4 関数・ポインタ・制御構文 | Developers.IO
http://dev.classmethod.jp/server-side/language/golang-4/

Goでは引数の渡し方はすべて値渡しとなります。(Javaのオブジェクトのような参照渡しはない)
ポインタを渡した場合もポインタの値渡し(ポインタのコピー)となるので、
オブジェクトのサイズによるメモリの無駄が少なくてすみます。

ポインタがわからない① - 今川館
http://imagawa.hatenadiary.jp/entry/2016/12/19/190000

Point型とPoint型は別物と区別され、後者は先頭に「&」をつけて表記される。
間接演算子
を使うと、ポインタの本体をコピーする。

混乱してきた。。構造体にPOINTって名前をつけてる??

  • 「*」はポインタをつくるときに右辺で使う
  • ポインタに対して「*」を使うとアドレスの先の値を得られる
  • 関数の引数は全て値渡しでメモリのコストが生じる
  • 「&」と「*」の重ねがけは混乱する
  • 型指定の「*」はポインタ型
  • 関数の引数だけではなく、レシーバーから変数が入ってくる。レシーバーがポインターの場合には注意?
  • ポインタ渡しする型がスカラ型かどうかとかもパターンがあるはず

関数とポインタ — プログラミング言語 Go | text.Baldanders.info
http://text.baldanders.info/golang/function-and-pointer/

関数の calling sequence としては v.Add(dv) と Vertex.Add(v, dv) は等価である。 つまり v は Add() 関数の0番目の引数として振る舞い,「値渡し」でセットされる。
Method receiver の型をポインタ型にすれば「参照渡し」にできる。
この場合も calling sequence としては v.Add(dv) と (*Vertex).Add(v, dv) は等価である。

暗黙的変換とかいろいろとコードベースで書いてる。

ポインタレシーバについて眺める

gormaでつくられた関数を眺めると謎が謎を呼んできた。。

// レシーバ(ポインタを渡す)、関数名、返り値の型
func (m *Model) Hoge() *app.Hoge {
    user := &app.Hoge{}
    // あれアドレス演算子?なんで?
    // 多分、レシーバーから受け取る変数はポインタではないらしい。
    // そして、アドレス演算子でアドレスを代入してるっぽい。多分。
    // 必要なければ普通に値を入れていいのかと。
    user.Contents = &m.Contents
    user.ID = &m.ID
    user.Name = &m.Name
    return hoge
}

ここでは、モデルの値をアドレス演算子でポインタを作って、
参照する形であたらしいオブジェクトを返していると思われる。
代入される側の構造体の定義にはポインタ文字列型とかになっているので、
つじつまが合う。。
なるほど。。賢いなあ。。
でも、複雑化してて面倒だなあ。。

速習Go。Fukuoka.go#1用の資料です。
https://gist.github.com/monochromegane/8bb73390f2ebd9d325f4

golang チートシート - Qiita
http://qiita.com/jca02266/items/56a4fb7b07b692a6bf34