今日から始める go言語 と appengine

56
今日から始める Go 言語 appengine 2014/01/24@FFTT 勉強会 inoue

Upload: a-know

Post on 04-Jun-2015

4.857 views

Category:

Technology


2 download

DESCRIPTION

「今日から始める Go言語 と appengine」というテーマで社内勉強会を実施した際に使用した、発表資料です。元記事 → http://tech.feedforce.jp/start-go-and-appengine.html

TRANSCRIPT

Page 1: 今日から始める Go言語 と appengine

今日から始める Go言語 と appengine

2014/01/24@FFTT勉強会 inoue

Page 2: 今日から始める Go言語 と appengine

Introduction

• 今日なにやるの?

- Go言語 で appengine を始めてみよう

- appengine でGo言語を始めてみよう

- 何かしら動くものを作ってみます - 今日からすぐにやってみよう、という気持ちになってもらえれば!

Page 3: 今日から始める Go言語 と appengine

Do you know golang?• 2009年11月10日(米国時間)に Google よりリリース。OSS

• Simple • コンパイル・実行速度が速い • タイプセーフかつメモリセーフ

• 並行処理の記述が容易にできる(goroutine)

• Google トレンド急上昇中

• 「2014年 プログラミング大予測」(日経ソフトウェア2014年2月号特集)にて「Go言語 のキャズム超え」を挙げる方も(@t_wada)

Page 4: 今日から始める Go言語 と appengine

Do you know appengine?• 正式名称「Google App Engine」(略称GAE)

• Google 謹製の PaaS、プログラムを書いてデプロイするだけで全世界に公開!

• AutoScaling • KVS(Datastore)

• 小さなアプリであれば無料枠運用も可能

- AWSのような「1年間無料」とかではなく、各アプリごとに無料で使える範囲が設定されている

- http[s]://<app-id>.appspot.com/ - 私もいくつかのアプリを運用しほったらかしています

Page 5: 今日から始める Go言語 と appengine

Why start appengine with golang?• spin-up は appengine の特徴のうちの一つ

- (捌き切れない)リクエストが来たら、新しいインスタンスを立ち上げる(=AutoScaling)

- これがJavaとかだと無茶苦茶遅い(~数秒)

• Python, Java, PHP の他、Go のサポートを開始

• Go だと spin-up はチョー速い(~数十ミリ秒)

• 「並列処理を書きやすい」のも、appengine アプリを書くのに適してる

- appengine の色んな機能を call するときの I/O 待ちを最小化

• appengine やるなら Go で、でしょ!状態

- (※まだexperimentalです)

Page 6: 今日から始める Go言語 と appengine

Agenda

1. Introduction i. Do you know golang? ii. Do you know appengine? iii. Why start appengine with golang?

2. About golang specification 3. Live developing 4. まとめ

Page 7: 今日から始める Go言語 と appengine

About golang specification

• まずは言語仕様から軽く・・・

• A Tour of Go - http://tour.golang.org/ - 実行するコードは、golang.org サーバ上のGo Playgroundで動作

- 受けたGoコードをサーバでコンパイル・リンク・実行し、そしてその結果を返してくれる

• A Tour of Go (jp) - http://go-tour-jp.appspot.com/ - 今日はここから要所をピックアップすることにします - 数が多いので巻き気味でいきます

Page 8: 今日から始める Go言語 と appengine

About golang specification #1) Hello World

Page 9: 今日から始める Go言語 と appengine

About golang specification #4) Packages

• プログラムの動作の始点は main パッケージ内

• パッケージ名はインポートパスの最後の要素と同じになる

- “math/rand” パッケージに属するプログラムは、 “package rand” から始まるコード群で構成される

Page 10: 今日から始める Go言語 と appengine

About golang specification #6) Exported names

• パッケージをインポートすると、そのパッケージが外部に公開(エクスポート)している名前(変数や関数)を参照することが可能 - 名前の最初が大文字で始まる場合はエクスポートされる

- Hoge ならエクスポートされるが、 hoge だとされない

Page 11: 今日から始める Go言語 と appengine

About golang specification #7, 8, 9, 10) About Functions

• 引数定義では、型が変数名の後にくるので注意。戻り値の型は引数定義の後ろに • 2つ以上の関数の引数が同じ型である場合には、最後の型だけ書くことができる • 複数の戻り値を返すことが可能

• 戻り値にもパラメータを取ることも可能(その場合、return だけ書けば良い)

Page 12: 今日から始める Go言語 と appengine

About golang specification #11, 12, 13) Variables

• var ステートメントで変数を宣言

• 2つ以上連続した変数の型が同じなら、最後に一回だけ書けばOK(関数の引数リストと同じ)

• 変数一つ一つに initializer を与えることも可能。その場合、型は省略できる

• := を用いることで暗黙的な型宣言も可能

- Ruby でいう ||= に似てるなー

Page 13: 今日から始める Go言語 と appengine

About golang specification #14) Basic types

• Go の基本型は以下。

- bool - string - int int8 int16 int32 int64 - uint uint8 uint16 uint32 uint64 uintptr - byte - rune - float32 float64 - complex64 complex128

Page 14: 今日から始める Go言語 と appengine

About golang specification #15) Constants

• 定数は、キーワード const を使って宣言

• character、string、boolean、数値(numeric)のみで宣言可能

• := を使っての宣言は不可

Page 15: 今日から始める Go言語 と appengine

About golang specification #17, 18, 19, 20) For

• Go でのループ処理に使えるのは for ループだけ、while はない

• 括弧 ( ) はつけてはならない。中括弧 { } は必要

• 条件の前後は空にできるし、セミコロンを抜くこともできる … これが Go での while!

• 条件を省略すれば無限ループに

Page 16: 今日から始める Go言語 と appengine

About golang specification #21, 22, 23) If

• 括弧 ( ) はつけてはならない、中括弧 { } は必要

• 条件式の前に短いステートメントを記述することができる

- ここで宣言された変数は、else ブロック内でも使える

Page 17: 今日から始める Go言語 と appengine

About golang specification #25, 26) Structs

• struct(構造体)というものがある

• フィールドにはドットを用いてアクセス

Page 18: 今日から始める Go言語 と appengine

About golang specification #27, 29) Pointers, The new function

• new(T) と書くと、ゼロ初期化した T の値をメモリに割り当て、そのポインタを返す

- Go にはポインタがある(ポインタ演算はない)

- 構造体のフィールドは、構造体のポインタを通してもアクセスできる

Page 19: 今日から始める Go言語 と appengine

About golang specification #30, 31, 32) Slices

• 配列変数は配列全体。スライスとは、ある配列内の連続した領域への参照のこと

• make 関数を使って生成:ゼロ初期化した配列をメモリに割り当て、その参照が生成される

Page 20: 今日から始める Go言語 と appengine

About golang specification #34, 35) Range

• slice などの要素ひとつずつを反復処理するのに使える

• i はインデックス。その後ろに変数を置くと値が取れる

• インデックスや値の代入先をアンスコ”_”にすることで、破棄することも可能

Page 21: 今日から始める Go言語 と appengine

About golang specification #37, 38, 39, 40) Maps

• 連想配列。make関数 で作成

• キーが存在するかどうかは、2つ目の戻り値を受け取ることで確認

- map m に key があれば、 ok は true になる

- なかった場合、ok は false になり、 v は、map の要素の型のゼロの値になる

Page 22: 今日から始める Go言語 と appengine

About golang specification #42, 43) Function

• 関数も値として扱える - 関数そのものを変数に代入できる

• Go の関数はクロージャだそうです

- クロージャ:関数閉包。引数以外の変数を自身のスコープにおいて解決する関数オブジェクト

- pos, neg の各クロージャは、自身の変数 sum へアクセスして変更できる(「sum にバインドされている」)

Page 23: 今日から始める Go言語 と appengine

About golang specification #45, 46) Switch

• 上から下に評価。一致したところから下は評価されない

• 各 case の最後で break する

- Java とかだと、case 文を実行した後でも switch 文全体の処理から抜けずに次の case の判定を行う

- fallthrough 文を case の最後に記述すれば、 Java とかと同じ挙動に

Page 24: 今日から始める Go言語 と appengine

About golang specification #50, 51) Methods

• メソッドの定義は、任意の type に対してのメソッドレシーバを定義することで行える(Go にはクラスの仕組みがない)

- Vertex に対して Abs() が呼び出されたら func Abs() が実行される

- 他のパッケージからの型や基本型にはメソッドを定義できない

Page 25: 今日から始める Go言語 と appengine

About golang specification #52) Methods with pointer receivers

• メソッドレシーバは、ポインタ型でも値型でも書ける

• pointer receiver を使うことで、各メソッド呼び出しで値をコピーするのを回避(元の値を変更)できる

• Scale メソッドが value receiver だった場合、元の値を変更することができない(元の値のコピーに対する操作になる)

Page 26: 今日から始める Go言語 と appengine

About golang specification #53) Interfaces

• インターフェース型は、メソッド群として定義される。 • そのインターフェース型の値は、それらのメソッドを実装する任意の値、となる

Page 27: 今日から始める Go言語 と appengine

About golang specification #55) Errors

• エラーを表す際には、組込みのインターフェース型の error を使う

• 文字列を返す Error メソッドを実装しておく

• fmt パッケージの各種表示ルーチンは、error 型を渡された場合、自動的に Error メソッドを呼び出す

Page 28: 今日から始める Go言語 と appengine

About golang specification #63) Goroutines

• “goroutine” は、いわゆるスレッド(軽量)

• “go f(x, y, z)” と書けば、関数 f は新しい goroutine 上で実行される

• x, y, z の評価は現在の goroutine(スレッド)で評価され、新しい goroutine で実行されるのは、関数 f

• goroutine は同じアドレス空間で実行されるため、共有メモリへのアクセスは、きちんと同期する必要がある…

Page 29: 今日から始める Go言語 と appengine

About golang specification #64, 65) Channels

• goroutine 間での通信には channel を用いる

• ch <- hoge で、hoge をチャネル ch に送る

• fuga <- ch で、チャネル ch から fuga を受信する

• チャネルも make 関数で作る。2つ目の引数にバッファ長を与えられる(チャネルはバッファ可能)

Page 30: 今日から始める Go言語 と appengine

About golang specification #66) Range and Close

• 送り手は、これ以上の送信する値がないことを示すためにチャネルを close できる

• for i := range c と書けば、チャネルが閉じられるまで、繰り返しチャネルから値を受信できる

Page 31: 今日から始める Go言語 と appengine

もう言語仕様はこれくらいにして…

Page 32: 今日から始める Go言語 と appengine

Live Developing

• せっかくなので、Webアプリっぽい挙動をするものを

- なおかつ、勉強会の時間内で完成するようなもの

- Mashupなかんじで、「はてなスターチェッカー」を作る!

- http://developer.hatena.ne.jp/ja/documents/star/apis/count

• Googleアカウントを作るところからやりますので、みなさんもぜひ、おうちでやってみてください!

Page 33: 今日から始める Go言語 と appengine

Live developing #1) install golang

• $ brew install go • python 2.7.x 以上が必要とのこと

- $ python --version • 作業を行うロケーションを GOPATH として設定しておくと便利って誰かが言ってた

- $ mkdir $HOME/go - $ export GOPATH=$HOME/go

• さらに bin サブディレクトリにもPATHを通しておくと便利らしいけど appengine 開発にはあまり関係ないかも

- $ export PATH=$PATH:$GOPATH/bin

Page 34: 今日から始める Go言語 と appengine

Live developing #2) Download appengine SDK

• https://developers.google.com/appengine/downloads?hl=ja にいく

• 「Google App Engine SDK for Go」がちゃんとあるので、ダウンロード

• 適当なところに展開

• 展開してできたディレクトリを PATH に通しておく

- $ export PATH=$PATH:$GOPATH/go_appengine

Page 35: 今日から始める Go言語 と appengine

Live developing #3) Hello World (1)

• 公式チュートリアルのHello Worldをやってみましょう

- https://developers.google.com/appengine/docs/go/gettingstarted/helloworld

• $ cd $GOPATH • $ mkdir -p workspace/hello • $ cd workspace/hello

Page 36: 今日から始める Go言語 と appengine

Live developing #3) Hello World (2)

• hello.go を作る

Page 37: 今日から始める Go言語 と appengine

Live developing #3) Hello World (3)

• 設定ファイル app.yaml を書く

• hello.go と同じ階層でOK

Page 38: 今日から始める Go言語 と appengine

Live developing #3) Hello World (4)

• ローカルでサーバを立ち上げてみる

- $ goapp serve . • http://localhost:8080 にアクセスしてみる

- 上のような画面が表示されたらOK

Page 39: 今日から始める Go言語 と appengine

Live developing #4) Take an Google Account (1)

• http://appengine.google.com/ にいく

• 「アカウントを作成」しましょう

Page 40: 今日から始める Go言語 と appengine

Live developing #5) create appengine application (1)

• 「Create Application」ボタンを押せば appengineアプリケーションの作成が始まります

• 電話認証が必要な場合があります

Page 41: 今日から始める Go言語 と appengine

Live developing #5) create appengine application (2)

• 「Application Identifier」には、世界でユニークなアプリケーション識別子を入力します(これは覚えておこう)

• 「Application Title」は、自分がわかるような文字列ならなんでもOK

• その他もそのままでOK

• 1アカウントで10アプリまで作れます

Page 42: 今日から始める Go言語 と appengine

Live developing #5) create appengine application (3)

• Congraturations !!

Page 43: 今日から始める Go言語 と appengine

Live developing #6) Deploy Application to appengine (1)

• 先ほどの Hello World をデプロイしてみましょう

- $ goapp deploy . • GMailアドレスとパスワードを聞かれます

• もしデプロイに失敗したりした場合、前回のデプロイ作業をロールバックさせる必要があります

- $ $GOPATH/go_appengine/appcfg.py rollback .

Page 44: 今日から始める Go言語 と appengine

Live developing #6) Deploy Application to appengine (2)

• デプロイが完了したら、先ほど覚えておいたアプリケーション識別子を下記URLに当てはめてアクセス!

- http://<application-identifier>.appspot.com/ • さきほどのローカル実行時と同じ画面が表示されたら、

Congraturations !! • いま、あなたの Hello World は全世界に公開されました!

Page 45: 今日から始める Go言語 と appengine

Live developing #7) Develop “star-checker” (1)

• では、このHello Worldをベースに、本来の目的の「はてなスターチェッカー」を作ってみましょう

• まずはルーティングを追加・変更します

Page 46: 今日から始める Go言語 と appengine

Live developing #7) Develop “star-checker” (2)

• チェック結果(APIからのレスポンス)を表す struct を作成します

• 変数名を大文字にして、Export可能にしておきます

Page 47: 今日から始める Go言語 と appengine

Live developing #7) Develop “star-checker” (3)

• htmlのテンプレートを作りましょう

• ちゃんとしたWebアプリをつくるときは、普通にhtmlを置いてAjaxでDOM操作するとか…

Page 48: 今日から始める Go言語 と appengine

Live developing #7) Develop “star-checker” (4)

• トップページのルーティングハンドラを作りましょう - いまあるハンドラは消しちゃいましょう - 初期表示としては空っぽの結果表示をしておくことにしましょう、そのために、空の StarReport をテンプレートに食わせときましょう

Page 49: 今日から始める Go言語 と appengine

Live developing #7) Develop “star-checker” (5)

• APIのレスポンスは JSON なので、それを parse する メソッドを定義

- StarReport に JsonProc というメソッドレシーバを定義する形

- JSON の parse 処理は今回の本質ではないので、さらっと

Page 50: 今日から始める Go言語 と appengine

Live developing #7) Develop “star-checker” (6)

• 最後に、チェックボタンをsubmitされたときのルーティングハンドラを作りましょう

- WebAPIを、appengine 上のアプリケーションからリクエストする際には、appengine の「URL Fetch」というAPIを用います

- appengine の機能を利用する際には、予め context を取得しておく必要があります

- (続きます)

Page 51: 今日から始める Go言語 と appengine

Live developing #7) Develop “star-checker” (7)

• 続きです

- APIのレスポンスの body を ioutil.ReadAll で取得します

- defer : これを実行した関数がリターンする直前に、defer で指定した関数の呼び出しが行われるようにスケジューリングしてくれる

- (さらに続きます)

Page 52: 今日から始める Go言語 と appengine

Live developing #7) Develop “star-checker” (8)

• さらに続きです

- string( hoge ) で、文字列に変換

- さっきのメソッドレシーバにより、parse された内容は report に

- その report をテンプレートに食わすと…

Page 53: 今日から始める Go言語 と appengine

Live developing #8) Congraturations!!

• できたっ!!

- あとはこれをもう一度デプロイすれば、Webアプリ「はてなスターチェッカー」の全世界へのリリースが完了です!

- スターの数がわりと少ないのは、バグではないです。

Page 54: 今日から始める Go言語 と appengine

Live developing #9) Appendix

• コード全文は下記にて公開しております

- https://github.com/a-know/star_checker

Page 55: 今日から始める Go言語 と appengine

• Goの言語仕様をざっと見てみました

• 実際にHello World と はてなスターチェッカー のふたつのアプリを書いてみました

• appengine にデプロイしてみました

• 言語はやっぱり使っていかないと習得できない!けど、appengineはそれにじゅうぶん応えてくれる(勉強目的くらいならタダで使える)プラットフォームだよ!

まとめ

Page 56: 今日から始める Go言語 と appengine

今日から始めましょう! Go言語 と appengine !!