1 of 25

Golang Cafe版

あなたがGoについて、

たぶん知らない10のこと。

Takashi Yokoyama @GDG Chugoku

2 of 25

I’m “not” professional.

  • GDG TyuChugoku Organizer (2010-)
  • 趣味
    • Google Apps / GCP関係
    • Golang / Dart
  • プログラマ(6年)→フリーランス(5年)→臨時的任用の公務員(1年7ヶ月)→来年正式採用予定

3 of 25

今日は

Golang Cafeというイベントで

議論になったポイントと

Go1.4の新機能に関する事を

紹介します

4 of 25

  1. Goroutine is not thread.
  • Goroutineはスレッドではない。
  • go func() {...}で生成できるがすぐに実行されない。
  • Goroutineはキューのように溜まっていく
  • ワーカースレッドがgoroutineをキューから取り出して実行する。

5 of 25

  1. Goroutine is not thread.
  • 本当にマルチスレッドで動かしたい時は
    • runtime.GOMAXPROCS(runtime.NumCPU())
    • runtime.GOMAXPROCS()は初期値が1
      • これを変更することで、挙動が変わる。
  • キューなので、goroutineはどんどん作って構わない。

6 of 25

  1. Goroutineの切り替え
  • Goroutineの切り替わりのタイミング
    • 明示的にブロックする時
      • net.TCPListener#Accept()
      • http.ListenAndServe()
      • time.Sleep()
      • Channel受信待ち
    • ファイルに書き込むとか、imageデータの書き込みでは切り替わらない。

7 of 25

  1. panic()の使い所
  • 例外機構として使えるが…。
    • panic()を呼び出した後、recover()を呼び出すことでプログラムが終了することは防げる。
      • recover()はdeferで登録した関数内のみで使える。
      • Golang標準パッケージでも使っているのはいくつかだけ。(代表的なものはencoding/json)
        • jsonは構文エラーがある時などで、一気に戻らないといけないため。

8 of 25

  1. panic()の使い所
  • Golangでは、エラーを関数の戻り値として返し、その場でエラー処理をすることが推奨されている。
  • 従って、panic()を呼び出す時は「どうしようもない時」
    • 例)fmt.Printf()が失敗した。
      • →これは、恐らく何かが壊れている。

9 of 25

  1. os.Exit()、log.Fatalf()
  • 関数が終わった後に呼び出されるdefer
  • os.Exit()や、log.Fatalf()などは、呼び出すとプロセスを終了してしまう。
    • deferで後処理されるべきものが呼び出されないことに。
    • どうしても後処理したい事があるならきれいにmainとgoroutineを終わらせましょう。

10 of 25

  1. errorの比較の罠
  • 自分で定義したerrorを作る方法
    • errors.New(“任意のテキスト”)
    • fmt.Errorf(書式, …)
  • グローバル変数に先に作っておかないとオブジェクトが違うので一致しない。

11 of 25

  • errorの比較の罠
  • 関数から返すerrorオブジェクトも定義したものを返してあげるようにする。
    • 面倒だから、fmt.Errorf(“エラー\n”)とすると、呼び出し側が困ることになるかもしれない。

12 of 25

ここからは

Go 1.4に関すること

13 of 25

  1. for文の仕様変更
  • for k, v := range x {...}
  • for v := range x {...}
    • 必ず値を受け取る変数を記述しなければいけなかった。
  • 受けとりたくない時
    • for _ = range x {...}

14 of 25

  • for文の仕様変更
  • Go 1.4から
    • for range x {...}
    • 省略することが可能になりました。

15 of 25

  1. GoをAndroidで動かす
  • go.mobileパッケージ
    • 公式サブパッケージ
    • Android NDKとして動作させる。
    • (当然) Javaから呼び出す事も可能。
    • サンプルを動かすまでのQiitaの記事を書いておきました。(先ほど追記しました)

16 of 25

  1. GoをAndroidで動かす
  • できること。
    • 描画:drawコールバック
    • タッチ:touchコールバック
  • これからのTodo
    • Activityのライフサイクルに対応した関数の実装?

17 of 25

  1. GoをAndroidで動かす

18 of 25

  1. TestMain関数の追加
  • これまでのUnitTestは、テストごとにsetup/teardownの処理を記述する必要があった。
  • func TestMain(m *testing.M)が追加された。
    • 全てのテストに共通のsetup/teardown処理が記述できるようになる。

19 of 25

  1. go generateコマンド追加
  • ファイルの先頭にコメントでコマンドを記述
    • 書式://go:generate [任意のコマンド] パラメータ...
    • 例://go:generate gen
      • genコマンドを実行(typeに合わせて便利な関数を生成)

20 of 25

  1. その他目についた変更
  • syscallパッケージがgo.sysパッケージに
    • 1.3までは、syscallパッケージに複数のOSのコードがあった。
    • 1.4からはsyscallパッケージは凍結
      • go.sysパッケージで各OSごとの処理が実装される
      • 1.3までの互換性は残ります。

21 of 25

  • その他目についた変更
  • Canonical import paths
    • 標準のimport先を明記するとコンパイル時にチェック。(ディレクトリ構成が違うとエラーになる)
    • package hello // import “github.com/tyokoyama/canonicalsample/hello”
    • 例えば、githubから他のリポジトリに移動させた時など、正規のリポジトリのものを使って欲しい時に使える。

22 of 25

  • その他目についた変更
  • File name handling
    • 以前は、”windows.go”とか、”amd64.go”と書いてあっても正しくコンパイルされていた。
    • 1.4からは、”os_windows.go”とか、”support_amd64.go”という命名が強制される。
    • ちなみに、Goのファイル名を_で区切るとコンパイル時に環境に合うものを選択してコンパイルしてくれる。

23 of 25

  1. その他目についた変更
  • 公式サブパッケージのパスがGoogle Codeからgolang.orgに移行
    • golang.org/x/...となる。(2015年6月から正式に)
    • もうすでに、go get 可能です。
  • Goのリポジトリがgithubに移行
    • hgコマンドからの解放(?)
    • gitのみでGoの運用ができるかも?

24 of 25

公開資料

  • サンプルコード(今日のDemo)

25 of 25

ご清聴ありがとうございました。