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

7,824 views

Published on

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

Published in: Technology
  • 資料の各ページについて、補足やコメント、勉強会の場でもらった質疑応答をこちらで。。

    p.3
    Go言語の人気のすごさは、ぜひ Googleトレンド(http://www.google.co.jp/trends/explore#q=golang)を見てみて下さい!


    p.4
    appengine は、アプリケーションIDごとに無料で使える範囲が設定されています:)
    利用開始の際は、AWS とかとは違って、クレジットカードの登録は必要ありません!
    無料範囲を超えたらレスポンスを返せなくなるだけ・・・うっかりヘンなアプリをデプロイしてしまって暴走してしまったりしても、課金破産の心配はありません!


    p.5
    spin-up の速度について。以前 Java の spin-up について測定してみたところ、10回の測定の平均が約4秒、という結果に・・・
    それに対し、Go での平均は約80msecでした
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • p.10
    変数名の先頭の文字が大文字でないとエクスポートされません(他パッケージからの参照ができません)
    このサンプルコードの場合、10行目で参照できないというエラーが発生します
    (math.pi は定義されていない変数でもあるので、undefined エラーも発生します)


    p.11
    関数の定義は、「func 関数名(引数定義) (戻り値定義)」という感じになります
    戻り値にもパラメータを取ることが可能で、その場合、return 命令で戻り値として定義したパラメータが、定義した順番で返ります


    p.12
    ここで、変数のスコープについての質問がありました(その場では答えられませんでした...)
    Go言語でのスコープ制御は、「ブロック」という考え方で行われます。
    関数の外で宣言されている変数については、そのスコープは「パッケージブロック」となり、同じパッケージであればアクセス可能、となります
    異なるパッケージからもアクセス可能としたければ、変数名の先頭文字を大文字、ですね:)
    関数内で宣言されている変数のスコープは、その関数内となります
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • p.20
    値の代入先をアンダースコア('_')にすることで破棄することができる、という点について、「それは慣習的なものなのか、それとも言語仕様としてそのような挙動をサポートしているのか」という質問を頂きました
    その場で検証してみたところ、後者・「代入先をアンダースコアにした場合、値を破棄するということが、言語仕様としてサポートされている」でした。


    p.24, 25
    Go言語でのメソッドの定義は、任意の type に対してメソッドレシーバを定義する、ということで行います
    メソッドレシーバは、ポインタ型レシーバと値型レシーバの2種類の定義の仕方があります
    元の値を変更できるようにしたければ、ポインタ型レシーバを選択します(メソッド呼び出しに伴う値のコピーを防ぐことができる)
    そうでなければ、値型レシーバを選択します(元の値のコピーに対する操作を行うメソッドが定義できる)


    p.26
    このページに載せているサンプルコードだと、22行目でエラーとなります
    変数 a は、インターフェース Abser 型の値です。インターフェース Abser 型の値は、 float64 の値を返す Abs() メソッドを実装している必要があります
    変数 f は MyFloat 型で、MyFloat 型に対するメソッドレシーバがちゃんと定義されているので、17行目の代入はエラーなく行うことができます
    変数 v は 構造体 Vertex ですが、18行目の代入の際に v の参照を代入、という形をとっているため、別途定義してあるポインタ型メソッドレシーバがあるので、この代入もエラーなく行えます
    一方で、22行目は変数 v をそのまま a に代入しようとしているため、エラーとなります
    40行目のメソッドレシーバをポインタ型レシーバから値型レシーバに変えれば、エラーは起こらず実行できるようになります
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • p.28
    goroutine は、「並列処理」ではなく「並行処理」になります
    ですが、appengine 上で動かすということを考えると、RPCの待ち時間の効率化が図れます
    appengine は各種機能をリモートプロシージャコール(RPC)で実現しており、ここが速度の妨げになることもしばしば
    一つのリクエストで複数のRPCが発生するような場合、goroutine を活用することで効率化が図れる!


    p.41
    p.37 で作成した app.yaml の「application」には、ここで取得した「Application Identifier」を記述する必要がありますのでご注意を...


    p.46, 47
    struct 内の各変数をエクスポート可能にしていますが、テンプレートの機能を使うときにはどうやら「パッケージ外からの変数へのアクセス」と同じような位置づけになるらしく、このようにしています
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

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

  1. 1. 今日から始める Go言語 と appengine 2014/01/24@FFTT勉強会 inoue
  2. 2. Introduction • 今日なにやるの? - Go言語 で appengine を始めてみよう - appengine でGo言語を始めてみよう - 何かしら動くものを作ってみます - 今日からすぐにやってみよう、という気持ちに なってもらえれば!
  3. 3. Do you know golang? • 2009年11月10日(米国時間)に Google よりリリース。OSS • Simple • コンパイル・実行速度が速い • タイプセーフかつメモリセーフ • 並行処理の記述が容易にできる(goroutine) • Google トレンド急上昇中 • 「2014年 プログラミング大予測」(日経ソフトウェア2014年2 月号特集)にて「Go言語 のキャズム超え」を挙げる方も (@t_wada)
  4. 4. Do you know appengine? • 正式名称「Google App Engine」(略称GAE) • Google 謹製の PaaS、プログラムを書いてデプロイするだけで 全世界に公開! • AutoScaling • KVS(Datastore) • 小さなアプリであれば無料枠運用も可能 - AWSのような「1年間無料」とかではなく、各アプリごとに 無料で使える範囲が設定されている - http[s]://<app-id>.appspot.com/ - 私もいくつかのアプリを運用しほったらかしています
  5. 5. 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です)
  6. 6. 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. まとめ
  7. 7. 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/ - 今日はここから要所をピックアップすることにします - 数が多いので巻き気味でいきます
  8. 8. About golang specification #1) Hello World
  9. 9. About golang specification #4) Packages • プログラムの動作の始点は main パッケージ内 • パッケージ名はインポートパスの最後の要素と同じになる - “math/rand” パッケージに属するプログラムは、 “package rand” から始まるコード群で構成される
  10. 10. About golang specification #6) Exported names • パッケージをインポートすると、そのパッケージが外部に 公開(エクスポート)している名前(変数や関数)を参照 することが可能 - 名前の最初が大文字で始まる場合はエクスポートされる - Hoge ならエクスポートされるが、 hoge だとされない
  11. 11. About golang specification #7, 8, 9, 10) About Functions • 引数定義では、型が変数名の後にくるので注意。戻り値の型は引数定義の後ろに • 2つ以上の関数の引数が同じ型である場合には、最後の型だけ書くことができる • 複数の戻り値を返すことが可能 • 戻り値にもパラメータを取ることも可能(その場合、return だけ書けば良い)
  12. 12. About golang specification #11, 12, 13) Variables • var ステートメントで変数を宣言 • 2つ以上連続した変数の型が同じなら、最後に一回だけ書けばOK(関数の引数 リストと同じ) • 変数一つ一つに initializer を与えることも可能。その場合、型は省略できる • := を用いることで暗黙的な型宣言も可能 - Ruby でいう ||= に似てるなー
  13. 13. 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
  14. 14. About golang specification #15) Constants • 定数は、キーワード const を使って宣言 • character、string、boolean、数値(numeric)のみで宣言 可能 • := を使っての宣言は不可
  15. 15. About golang specification #17, 18, 19, 20) For • Go でのループ処理に使えるのは for ループだけ、while はない • 括弧 ( ) はつけてはならない。中括弧 { } は必要 • 条件の前後は空にできるし、セミコロンを抜くこともできる … これが Go での while! • 条件を省略すれば無限ループに
  16. 16. About golang specification #21, 22, 23) If • 括弧 ( ) はつけてはならない、中括弧 { } は必要 • 条件式の前に短いステートメントを記述することができる - ここで宣言された変数は、else ブロック内でも使える
  17. 17. About golang specification #25, 26) Structs • struct(構造体)というものがある • フィールドにはドットを用いてアクセス
  18. 18. About golang specification #27, 29) Pointers, The new function • new(T) と書くと、ゼロ初期化した T の値をメモリに割り当て、その ポインタを返す - Go にはポインタがある(ポインタ演算はない) - 構造体のフィールドは、構造体のポインタを通してもアクセスでき る
  19. 19. About golang specification #30, 31, 32) Slices • 配列変数は配列全体。スライスとは、ある配列内の連続した領域への参照のこと • make 関数を使って生成:ゼロ初期化した配列をメモリに割り当て、その参照が 生成される
  20. 20. About golang specification #34, 35) Range • slice などの要素ひとつずつを反復処理するのに使える • i はインデックス。その後ろに変数を置くと値が取れる • インデックスや値の代入先をアンスコ”_”にすることで、 破棄することも可能
  21. 21. About golang specification #37, 38, 39, 40) Maps • 連想配列。make関数 で作成 • キーが存在するかどうかは、2つ目の戻り値を受け取ることで確認 - map m に key があれば、 ok は true になる - なかった場合、ok は false になり、 v は、map の要素の型のゼロの値 になる
  22. 22. About golang specification #42, 43) Function • 関数も値として扱える - 関数そのものを変数に代入できる • Go の関数はクロージャだそうです - クロージャ:関数閉包。引数以外の変数を自身のスコープにおいて解決する関数オブジェクト - pos, neg の各クロージャは、自身の変数 sum へアクセスして変更できる(「sum にバインド されている」)
  23. 23. About golang specification #45, 46) Switch • 上から下に評価。一致したところから下は評価されない • 各 case の最後で break する - Java とかだと、case 文を実行した後でも switch 文全体の処理から抜けず に次の case の判定を行う - fallthrough 文を case の最後に記述すれば、 Java とかと同じ挙動に
  24. 24. About golang specification #50, 51) Methods • メソッドの定義は、任意の type に対してのメソッドレシーバを定義 することで行える(Go にはクラスの仕組みがない) - Vertex に対して Abs() が呼び出されたら func Abs() が実行される - 他のパッケージからの型や基本型にはメソッドを定義できない
  25. 25. About golang specification #52) Methods with pointer receivers • メソッドレシーバは、ポインタ型でも値型でも書ける • pointer receiver を使うことで、各メソッド呼び出しで値をコピーするのを回避 (元の値を変更)できる • Scale メソッドが value receiver だった場合、元の値を変更することができない (元の値のコピーに対する操作になる)
  26. 26. About golang specification #53) Interfaces • インターフェース型は、メソッド群として定義される。 • そのインターフェース型の値は、それらのメソッドを実 装する任意の値、となる
  27. 27. About golang specification #55) Errors • エラーを表す際には、組込みのインターフェース型の error を使う • 文字列を返す Error メソッドを実装しておく • fmt パッケージの各種表示ルーチンは、error 型を渡された場合、自動的に Error メソッドを呼び出す
  28. 28. About golang specification #63) Goroutines • “goroutine” は、いわゆるスレッド(軽量) • “go f(x, y, z)” と書けば、関数 f は新しい goroutine 上で実行される • x, y, z の評価は現在の goroutine(スレッド)で評価され、新しい goroutine で実行されるのは、関数 f • goroutine は同じアドレス空間で実行されるため、共有メモリへの アクセスは、きちんと同期する必要がある…
  29. 29. About golang specification #64, 65) Channels • goroutine 間での通信には channel を用いる • ch <- hoge で、hoge をチャネル ch に送る • fuga <- ch で、チャネル ch から fuga を受信する • チャネルも make 関数で作る。2つ目の引数にバッファ長を与えられる (チャネルはバッファ可能)
  30. 30. About golang specification #66) Range and Close • 送り手は、これ以上の送信する値がないことを示すためにチャネル を close できる • for i := range c と書けば、チャネルが閉じられるまで、繰り返し チャネルから値を受信できる
  31. 31. もう言語仕様はこれくらいにして…
  32. 32. Live Developing • せっかくなので、Webアプリっぽい挙動をするものを - なおかつ、勉強会の時間内で完成するようなもの - Mashupなかんじで、「はてなスターチェッカー」を 作る! - http://developer.hatena.ne.jp/ja/documents/star/ apis/count • Googleアカウントを作るところからやりますので、みな さんもぜひ、おうちでやってみてください!
  33. 33. 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
  34. 34. 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
  35. 35. 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
  36. 36. Live developing #3) Hello World (2) • hello.go を作る
  37. 37. Live developing #3) Hello World (3) • 設定ファイル app.yaml を書く • hello.go と同じ階層でOK
  38. 38. Live developing #3) Hello World (4) • ローカルでサーバを立ち上げてみる - $ goapp serve . • http://localhost:8080 にアクセスしてみる - 上のような画面が表示されたらOK
  39. 39. Live developing #4) Take an Google Account (1) • http://appengine.google.com/ にいく • 「アカウントを作成」しましょう
  40. 40. Live developing #5) create appengine application (1) • 「Create Application」ボタンを押せば appengineアプ リケーションの作成が始まります • 電話認証が必要な場合があります
  41. 41. Live developing #5) create appengine application (2) • 「Application Identifier」には、世界でユニークなアプリケーション識別子 を入力します(これは覚えておこう) • 「Application Title」は、自分がわかるような文字列ならなんでもOK • その他もそのままでOK • 1アカウントで10アプリまで作れます
  42. 42. Live developing #5) create appengine application (3) • Congraturations !!
  43. 43. Live developing #6) Deploy Application to appengine (1) • 先ほどの Hello World をデプロイしてみましょう - $ goapp deploy . • GMailアドレスとパスワードを聞かれます • もしデプロイに失敗したりした場合、前回のデプロイ作 業をロールバックさせる必要があります - $ $GOPATH/go_appengine/appcfg.py rollback .
  44. 44. Live developing #6) Deploy Application to appengine (2) • デプロイが完了したら、先ほど覚えておいたアプリケーショ ン識別子を下記URLに当てはめてアクセス! - http://<application-identifier>.appspot.com/ • さきほどのローカル実行時と同じ画面が表示されたら、 Congraturations !! • いま、あなたの Hello World は全世界に公開されました!
  45. 45. Live developing #7) Develop “star-checker” (1) • では、このHello Worldをベースに、本来の目的の「はてな スターチェッカー」を作ってみましょう • まずはルーティングを追加・変更します
  46. 46. Live developing #7) Develop “star-checker” (2) • チェック結果(APIからのレスポンス)を表す struct を 作成します • 変数名を大文字にして、Export可能にしておきます
  47. 47. Live developing #7) Develop “star-checker” (3) • htmlのテンプレートを作りましょう • ちゃんとしたWebアプリをつくるときは、普通にhtmlを 置いてAjaxでDOM操作するとか…
  48. 48. Live developing #7) Develop “star-checker” (4) • トップページのルーティングハンドラを作りましょう - いまあるハンドラは消しちゃいましょう - 初期表示としては空っぽの結果表示をしておくことにしましょう、 そのために、空の StarReport をテンプレートに食わせときましょう
  49. 49. Live developing #7) Develop “star-checker” (5) • APIのレスポンスは JSON なので、それを parse する メソッドを定義 - StarReport に JsonProc というメソッドレシーバを定義する形 - JSON の parse 処理は今回の本質ではないので、さらっと
  50. 50. Live developing #7) Develop “star-checker” (6) • 最後に、チェックボタンをsubmitされたときのルーティングハンドラを作りましょう - WebAPIを、appengine 上のアプリケーションからリクエストする際には、 appengine の「URL Fetch」というAPIを用います - appengine の機能を利用する際には、予め context を取得しておく必要があります - (続きます)
  51. 51. Live developing #7) Develop “star-checker” (7) • 続きです - APIのレスポンスの body を ioutil.ReadAll で取得します - defer : これを実行した関数がリターンする直前に、defer で指定した 関数の呼び出しが行われるようにスケジューリングしてくれる - (さらに続きます)
  52. 52. Live developing #7) Develop “star-checker” (8) • さらに続きです - string( hoge ) で、文字列に変換 - さっきのメソッドレシーバにより、parse された内容は report に - その report をテンプレートに食わすと…
  53. 53. Live developing #8) Congraturations!! • できたっ!! - あとはこれをもう一度デプロイすれば、Webアプリ「はてなスター チェッカー」の全世界へのリリースが完了です! - スターの数がわりと少ないのは、バグではないです。
  54. 54. Live developing #9) Appendix • コード全文は下記にて公開しております - https://github.com/a-know/star_checker
  55. 55. • Goの言語仕様をざっと見てみました • 実際にHello World と はてなスターチェッカー のふたつ のアプリを書いてみました • appengine にデプロイしてみました • 言語はやっぱり使っていかないと習得できない!けど、 appengineはそれにじゅうぶん応えてくれる(勉強目的 くらいならタダで使える)プラットフォームだよ! まとめ
  56. 56. 今日から始めましょう! Go言語 と appengine !! 完

×