2014/02/13


先日、Go言語バージョン1.1がリリースされました。安定しているのは勿論、幾つか新機能が追加されましたが、何よりもパフォーマンスチューニングが施された一番嬉しいですね。
Go 1.1 performance improvements | Dave Cheney

This is the first in a series of articles analysing the performance improvements in the Go 1.1 relea...

http://dave.cheney.net/2013/05/21/go-11-performance-improvements
さて今日はVimを使ってGo言語を開発する方法を紹介したいと思います。
VimでGo言語を開発するには、Go言語のリポジトリに含まれる misc/vim にランタイムパスを追加します。以下を vimrc に追加します。
set rtp+=$GOROOT/misc/vim

入力補完を行う

入力補完として gocode を入れます。正直、これは必須と言っていいです。
$ go get github.com/nsf/gocode
を実行します。$GOPATH/bin にインストールされるのでパスを通しておきましょう。
$GOROOT に入ってしまった人は一度削除して、$GOPATH を設定後にもう一度、上記のコマンドを実行します。
$GOPATH にインストールされているはずなので以下の様にvimrcに追加します。
exe "set rtp+=".globpath($GOPATH"src/github.com/nsf/gocode/vim")
gocodeを入れると、パッケージ名の途中であったり変数の後の "." をタイプした後<c-x><c-o> をタイプすると、あり得る関数名や、メソッド名がずらずらーっと補完出来ます。
gocode
その際、completeopt というオプションに preview を足しておくと、補完内容が詳細に表示されて分かりやすくなります。
set completeopt=menu,preview

パッケージをインポートする

Go言語でも、欲しい機能があればパッケージをインポートします。その際、いちいちファイルの先頭に移動して、import を追加したりしてませんか?上記のオフィシャルが提供しているVimプラグインを使っているのであれば、以下の様に実行しましょう。
:Import fmt
before
package main

func main() {
    fmt.Println("hello world")
}
after
package main

import (
    "fmt"
)

func main() {
    fmt.Println("hello world")
}
カーソルの移動もありませんので、引き続きコーディングが再開出来ます。また、コマンドの引数でパッケージ名の補完が効きます。net/ht までタイプして <tab> をタイプすれば net/http を補完してくれますし、ありえる候補も補完してくれます。

ドキュメントを見る

Go言語には godoc というツールが付属しています。コマンドラインから使っても便利なのですが、Vimから使うともっと便利になります。
:Godoc net/http
godoc

:Import と同様にパッケージ名が補完出来ます。

整形する

Go言語には go fmt というコマンドが付属しており、相応しいソースに整形する事が出来ます。
インデントが崩れたりした場合でも :Fmt
を実行するだけで、綺麗なソースコードに整形されます。

テンプレートを使う

手前味噌ですが、僕が作ってる sonictemplate-vim を使うと、ソースの書き始めが一気に楽になります。
mattn/sonictemplate-vim - GitHub
https://github.com/mattn/sonictemplate-vim
これを bundle ディレクトリ等に入れておき、goのファイルを新規で開きます。そこで
:Template web-app
を実行すれば以下のコードが展開されます。
package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.HandleFunc("/"func (w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "")
    })
    http.ListenAndServe(":8080"nil)
}
この後、http.ListenAndServe(":8080", nil) の1行上で空行を開け、:Template <tab> をタイプすると、web-app に特化した候補が優先的に表示されます。
sonictemplate
sonictemplate-vim はGo言語だけでなく、他の言語でも同様に便利なテンプレートが用意されています。よろしければ使ってみて下さい。また pull-req によるテンプレートの追加もお待ちしています。

これだけあれば、この夏のビーチでモテモテ間違いなしですね!

基礎からわかる Go言語 基礎からわかる Go言語
古川 昇
シーアンドアール研究所 単行本(ソフトカバー) / ¥465 (2012年11月21日)
 
発送可能時間:

Posted at by



2014/02/10


C言語の文字列伸張は慣れないとコストの掛かるコーディングになりがちです。
またそういった文字列ライブラリというのは、直接 puts や printf に放り込めないという難点があります。
しかし sds というライブラリは異なります。
antirez/sds - GitHub

Simple Dynamic Strings SDS is a string library for C designed to augment the limited libc ...

https://github.com/antirez/sds
通常、C言語向け文字列ライブラリというのは独自の構造体ポインタを返します。そうする事で、文字列ポインタ以外の情報を詰め込んで処理する事が出来ます。しかしその反面、構造体ポインタをそのまま puts や printf に放り込めず、何かしらのアクセサを用意する必要がありました。 printf("%s\n", string->buf);
しかし sds の場合はそれが出来ます。 printf("%s\n", sds_string); sds *tokens;
int count, j;

sds line = sdsnew("Hello World!");
tokens = sdssplitlen(line,sdslen(line)," ",1,&count);

for (j = 0; j < count; j++)
    printf("%s\n", tokens[j]);
sdsfreesplitres(tokens,count);

output> Hello
output> World!
トリックとしては、sds で生成された文字列は必ず sds 構造体のメンバに格納されている前提ですので、sds 文字列ポインタは構造体の先頭ポインタからのオフセット分シフトした所に位置します。
つまり sds 文字列ポインタからヘッダのバイト数分アドレスを戻せば、補足情報を得られるという仕組みです。
それの証拠に sdslen は以下の様なコードになっています。
static inline size_t sdslen(const sds s) {
    struct sdshdr *sh = (void*)(s-sizeof *sh);
    return sh->len;
}
個人的にはC言語での文字列操作は慣れてしまっているのでスルーで良いかなと思いましたが、仕組みは面白いと思いました。
Posted at by



2014/02/05


CSV ファイルを扱っている時に、最大値最小値と得たり合計を得たりするのにいちいち Excel を起動するのはとても面倒ですし、スクリプトを書くのも面倒。
そんな場合は textql を使うと便利です。
dinedal/textql - GitHub

Execute SQL against structured text like CSV or TSV

https://github.com/dinedal/textql
golang で書かれています。ビルドすると依存性の無い実行モジュールが生成されます。使い方はリンク先の動画gifを参照下さい。
簡単にどんな事が出来るかというと $ cat ~/sample_data.csv | textql -header -sql "select sum(cast(value as integer)) from tbl"
18
こんな事が出来るツールです。中身は実は sqlite3 を使っています。 ただ go-sqlite3 は amalgamation code を含んでいるので実行モジュールに依存物がありません。 textql-dependency
なので Windows なら exe 一つを USB メモリなんかに持っていればいざ困った時に使えるかもしれませんね。
Posted at by