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

Post on 04-Jun-2015

4.857 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

DESCRIPTION

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

TRANSCRIPT

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

2014/01/24@FFTT勉強会 inoue

Introduction

• 今日なにやるの?

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

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

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

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

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

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

• Google トレンド急上昇中

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

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

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

• AutoScaling • KVS(Datastore)

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

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

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

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です)

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. まとめ

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/ - 今日はここから要所をピックアップすることにします - 数が多いので巻き気味でいきます

About golang specification #1) Hello World

About golang specification #4) Packages

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

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

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

About golang specification #6) Exported names

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

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

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

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

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

About golang specification #11, 12, 13) Variables

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

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

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

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

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

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

About golang specification #15) Constants

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

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

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

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

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

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

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

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

About golang specification #21, 22, 23) If

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

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

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

About golang specification #25, 26) Structs

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

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

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

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

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

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

About golang specification #30, 31, 32) Slices

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

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

About golang specification #34, 35) Range

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

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

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

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

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

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

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

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

About golang specification #42, 43) Function

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

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

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

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

About golang specification #45, 46) Switch

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

• 各 case の最後で break する

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

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

About golang specification #50, 51) Methods

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

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

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

About golang specification #52) Methods with pointer receivers

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

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

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

About golang specification #53) Interfaces

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

About golang specification #55) Errors

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

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

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

About golang specification #63) Goroutines

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

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

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

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

About golang specification #64, 65) Channels

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

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

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

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

About golang specification #66) Range and Close

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

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

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

Live Developing

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

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

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

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

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

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

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

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

Live developing #3) Hello World (2)

• hello.go を作る

Live developing #3) Hello World (3)

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

• hello.go と同じ階層でOK

Live developing #3) Hello World (4)

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

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

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

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

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

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

Live developing #5) create appengine application (1)

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

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

Live developing #5) create appengine application (2)

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

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

• その他もそのままでOK

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

Live developing #5) create appengine application (3)

• Congraturations !!

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

- (続きます)

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

• 続きです

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

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

- (さらに続きます)

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

• さらに続きです

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

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

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

Live developing #8) Congraturations!!

• できたっ!!

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

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

Live developing #9) Appendix

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

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

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

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

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

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

まとめ

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

top related