Looks Go To Me

golang をゆったり学びます。

ポインタ型のレシーバー、ポインタ型の struct embed

golang の struct のレシーバーを struct への ポインタ型にした場合とか、エンベッドしたときにポインタ型にした場合とかの挙動の違いがいまいち把握できてなかったのですが、ポインタとはなんぞや、を思い出して納得しました。

  • メモリアローケーションされてないポインタを介しての参照は1部の例外をのぞいてすべて panic

これが原則として、では、例外とはなんぞや?ってことなんですが、

qiita.com

1つはこれですね。レシーバーがポインタの場合に限っては nil のポインタを介してメソッドの実行が可能。これは人によっては便利につかう場面もありそうです。

これは、structへのポインタとしてエンベッドされた埋め込み struct が nil の場合でも同様にその先のメソッドを呼べますが、もとの struct が nil だと、ダメです。えっとめんどいな。参照になるんですかねー。

続きは playground で。

The Go Playground

参考。本質的なことが書いてある(きがする

The empty struct | Dave Cheney

僕だけの最強の fresh

github.com

fresh というとても素敵なツールがありまして、大変お世話になっております。

でも、ちょっとこうしたいな、とか、これはちょっとみたいなのがあって、その辺機能追加されてるやつないかって探したわけです。

すると、なにしろ fork が 88 とかあって、すごい量なんだけど本家に取り込まれて無くてみんな独自の進化を走ってるんですね。

というわけで私も fork してつくりました。

起動オプション指定と toml 対応してる下記のリポジトリを fork

github.com

なぜか toml decode で panic るのをなおし、exclude path regexps を追加。

github.com

emacs でファイル保存するたびに .#app.go が build されるのを辞めたかったんです。

go enjoy go.

sql から struct をつくりたかった

golang で db あつかうときスキーマを struct で用意するじゃないですか。

で、sql はあるのでそっから struct つくりたかったんですが、見つからなかったので mysql に接続して情報を取得して struct を吐いてくれるやつを使いました。

github.com

結果てきには mysql 対応の実装が動いてなかったので、fork してなおしたやつを使いました。

github.com

あと、set 型未対応だったので、てきとうに *string に変換しておきました。

set が *string でいいかはまだこれから使ってみて考えよう

shasum を移植

shasum ってコマンドがあって、それ使ってたんですが、perl のコマンドだったのを今知って、go に劣化移植しました。

github.com

$go get github.com/sheercat/goshasum

$goshasum .gitconfig .bashrc
92c725e0c0c425ec6b46c66bf5a67cef1b567bed    .gitconfig
4734ff0808f8f2e1b4735891d04c3c70f5cb62d6    .bashrc

$goshasum -a md5 .bashrc
d7bd1936a083c8cca0f94d057015c3aa    .bashrc

C にはかなわないけど速い。よかった。

go 書籍あれこれ

あけまして。happy go year 2016

go (golang ) の書籍が増えてきましたので、ちょっと紹介します。

改訂2版 基礎からわかる Go言語

改訂2版 基礎からわかる Go言語

  • 現時点では、日本の本で1.4対応してるgo入門本では最適解ではないでしょうか。

Go言語によるWebアプリケーション開発

Go言語によるWebアプリケーション開発

  • これはまだ出てませんが、web アプリに特化してる邦訳本としては唯一になりそう。'
    • 原書がこちら↓

Go Programming Blueprints - Solving Development Challenges with Golang

Go Programming Blueprints - Solving Development Challenges with Golang

  • ちなみに、この原書は packtpub なら $5 $29.99 だそうです。

The Go Programming Language (Addison-Wesley Professional Computing)

The Go Programming Language (Addison-Wesley Professional Computing)

  • カーニハンです。kindle もありますね。
    • C といえばカーニハン&リッチー本なわけですが、果たして go でもそうなるでしょうか?レビューはのきなみ★5ですね。翻訳されたら即買います。
    • The Go Programming Language に電子版購入、一部のPDFのダウンロード、およびソースコードのある github へのリンクがあります。

Level Up Your Web Apps With Go

Level Up Your Web Apps With Go

Go in Action

Go in Action

golang regexp onepass とは

golangregexp には go1.3 以降から onepass っていう処理がはいって、never need backtracking な regexp は onepass として高速に処理されるらしい。

具体的にはどんなものが onepass になるのか、なれないのか。

それは onepass_test.go をみるのがてっとりばやそうだっった。

github.com

golang regexp の速度について

最近 regexp 系をいろいろさわってました。 golangregexp が c, ruby, perl などと比べて遅いというのはググったらいろいろ情報出てくるんですねー。

さて、regexp 処理がメインの perl モジュールを go に移植したんですが、チューニングしても 3倍以上の速度差がありました。(愚直に移植しただけだと10倍以上の差異)

pprof みると、

    46.11s 33.43% 33.43%     99.23s 71.95%  regexp.(*machine).tryBacktrack
    14.47s 10.49% 43.93%     14.47s 10.49%  regexp.(*bitState).push
    12.89s  9.35% 53.27%     15.67s 11.36%  unicode.SimpleFold
    11.57s  8.39% 61.66%     11.57s  8.39%  regexp.(*inputBytes).step
     9.44s  6.85% 68.51%     25.11s 18.21%  regexp/syntax.(*Inst).MatchRunePos
     3.80s  2.76% 71.26%    109.07s 79.09%  regexp.(*machine).backtrack
     3.25s  2.36% 73.62%     28.36s 20.56%  regexp/syntax.(*Inst).MatchRune

こんな感じで上位に居て、tryBacktrack かー、、、これ、正規表現を綺麗に書くとかで回避できる感じもあるけど、無理な場合もあるなーとか、結構サックり改善できそうもなかったです。

ちなみに、最初こんなコードを書いてたんですが

func (f Filler) unquote(tag []byte) []byte {
    newTag := f.compileMultiLine(`['"](.*)['"]`).FindSubmatch(tag)
    if cap(newTag) == 2 {
        return newTag[1]
    }
    return tag
}

こうなおしたら

func (f Filler) unquote(tag []byte) []byte {
    return bytes.Trim(tag, `'"`)
}

100倍早くなりました。

いまのところ、regexp を回避していくことが速度改善の秘訣のようです。

あと、pprof は Mac だとできない。これ、罠。