Slide 1

Slide 1 text

Go Hands-on #2 #techdo #golang #mediado #redish Nov 27, 2018 1 @kentfordev @yukpiz @ariaki4dev written by proofread CC-BY-4.0

Slide 2

Slide 2 text

タイムスケジュール 2 19:30 オープニング ( 10 min ) 19:40 座学 ( 40 min ) 20:20 課題/出題 ( 10 min ) 20:30 課題/解答 ( 50 min ) 21:20 課題/説明&クロージング ( 10 min ) 21:30 懇親会 22:00 撤収

Slide 3

Slide 3 text

登壇者の紹介 3 @k_h_sissp kentfordev @yukpiz yukpiz @ariaki4dev ariaki

Slide 4

Slide 4 text

座学 19:40 ~ 20:20 ( 40 min )

Slide 5

Slide 5 text

目次 5 Goコマンド Go標準パッケージ レシーバー インターフェース 本日の学習内容 並列処理/ゴルーチン 並列処理/チャネル コーディング規約 ユニットテスト

Slide 6

Slide 6 text

Goコマンド command-line parameters

Slide 7

Slide 7 text

Goコマンド 7 get run test fmt build bug clean doc env fix generate install list mod tool version vet コマンド一覧

Slide 8

Slide 8 text

Goコマンド 8 今回紹介するコマンド get run test fmt build bug clean doc env fix generate install list mod tool version vet

Slide 9

Slide 9 text

Goコマンド 9 get ● ライブラリをダウンロードして、プロジェクトで使えるようにする ● ダウンロード先は、環境変数の $GOPATH 配下が対象となる

Slide 10

Slide 10 text

Goコマンド 10 get dateライブラリをgetする $GOPATH/src/配下に、github.com/rickb777/dateがダウンロードされる ※-uオプションは、対象リポジトリの最新版を常に指定してダウンロードする

Slide 11

Slide 11 text

Goコマンド 11 run ● コマンド実行時に指定した、対象のプログラムを実行する ● コンパイル結果のファイルは生成せず、即時実行する

Slide 12

Slide 12 text

Goコマンド 12 run 先程のdateを使った、サンプルコード

Slide 13

Slide 13 text

Goコマンド 13 run 実行方法 ※実行結果として、「2018-11-27」が出力される

Slide 14

Slide 14 text

Goコマンド 14 fmt ● ソースコードを整形する ● パスの指定方法により、整形対象をファイル単体か、ディレクトリ全 体かを変えることができる

Slide 15

Slide 15 text

Goコマンド 15 fmt 整形前

Slide 16

Slide 16 text

Goコマンド 16 fmt 実行方法

Slide 17

Slide 17 text

Goコマンド 17 fmt 整形後

Slide 18

Slide 18 text

Goコマンド 18 test ● _test.goというサフィックスを持つファイルに対しテストを実行 ● 詳細は後述のテストの項目で説明

Slide 19

Slide 19 text

Goコマンド 19 build ● ソースコードをコンパイルし、実行ファイルを出力する ● 開発環境とは別の環境に向けた実行ファイルでも、オプションで指定 すれば、コンパイルすることができる

Slide 20

Slide 20 text

Goコマンド 20 build 実行方法 ※-oオプション無しの場合、goファイルの拡張子なしの名前が出力ファイル名になる

Slide 21

Slide 21 text

Goコマンド 21 build Windows向けのバイナリを出力する例 ※開発環境がLinux、macOS等であっても、main.exeという名前で出力される

Slide 22

Slide 22 text

Go標準パッケージ standard packages

Slide 23

Slide 23 text

Go標準パッケージ 23 標準パッケージとは ● Go自身に含まれるライブラリで、go getせずに使える ● 入出力周りやJSONパース、サーバ起動などの機能が提供されており、 これだけでもある程度の処理を作ることができる

Slide 24

Slide 24 text

Go標準パッケージ 24 fmt 標準入力・標準出力を扱う io データの入出力を扱う ( Writer / Reader ) log ログ出力機能を扱う 紹介するパッケージ

Slide 25

Slide 25 text

Go標準パッケージ 25 fmt 標準入力された文字列を標準出力する

Slide 26

Slide 26 text

Go標準パッケージ 26 io 先程の標準入力、標準出力のコードを、ReaderとWriterに置き換えてみる Reader/Writerはインターフェースとして定義されており、よく使われる

Slide 27

Slide 27 text

Go標準パッケージ 27 log 標準出力の対象をLoggerに変更し、標準入力の内容をログ出力する

Slide 28

Slide 28 text

Go標準パッケージ 28 log 実行結果

Slide 29

Slide 29 text

レシーバー receivers

Slide 30

Slide 30 text

レシーバー 30 レシーバーとは ● 定義した構造体に対して、関数を実装することができる ● 構造体のデータ取出/変更を、処理とセットにする事ができる ● 構造体の値に定義する「値レシーバー」 ● 構造体のポインタ型に定義する「ポインタレシーバー」

Slide 31

Slide 31 text

レシーバー 31 レシーバーの定義 サンプルとしてPerson構造体を作成

Slide 32

Slide 32 text

レシーバー 32 レシーバーの定義 AgeとNameに対するレシーバーを作成

Slide 33

Slide 33 text

レシーバー 33 レシーバーの定義 定義したレシーバーの呼び出し

Slide 34

Slide 34 text

レシーバー 34 値レシーバーとポインタレシーバー ● メモリ効率と用途によって、主にポインタレシーバーが使われる ● 値レシーバーでは呼び出し時に構造体自体を一旦コピーし、呼び出し 元の構造体とは別のものが処理対象になる ● ポインタレシーバーなら呼び出し元の値を変更することができる

Slide 35

Slide 35 text

レシーバー 35 値レシーバーとポインタレシーバー 下記のように値レシーバーで呼び出してしまうと、出力結果は29のまま

Slide 36

Slide 36 text

インターフェース interfaces

Slide 37

Slide 37 text

インターフェース 37 インターフェースとは ● 型が持つべき関数を定義することで、パッケージ間でやり取りする型 を抽象化することができる ● これにより構造体の型を隠蔽し、処理の抽象度を上げることができる ● ここではインターフェースの定義方法と、基礎的な使い方を説明する

Slide 38

Slide 38 text

インターフェース 38 インターフェースの定義 前章のPersonを踏襲する形でインターフェースを定義

Slide 39

Slide 39 text

インターフェース 39 インターフェースを受け取る インターフェースを引数に取る関数を作る

Slide 40

Slide 40 text

インターフェース 40 インターフェースを使う インターフェースの定義を満たす構造体を定義する、下記は前章のPerson

Slide 41

Slide 41 text

インターフェース 41 インターフェースを使う Person構造体はHumanインターフェースの定義を満たすため、whoAreYou()を実行できる 「My name is kent」が出力される

Slide 42

Slide 42 text

インターフェース 42 インターフェースを使う Personとは別に、新しく構造体を作る

Slide 43

Slide 43 text

インターフェース 43 インターフェースを使う Humanインターフェースの定義を満たすので、RobotもwhoAreYou()を実行できる 「My id is abcd」が出力される

Slide 44

Slide 44 text

インターフェース 44 引数、返却値がある関数の定義 インターフェースの関数に引数、返却値を定義する ※引数は変数名を書いておくこともできる

Slide 45

Slide 45 text

Short break (5 min)

Slide 46

Slide 46 text

並列処理 ゴルーチン go routines

Slide 47

Slide 47 text

並列処理 ゴルーチン 47 ● ゴルーチンはGo言語で並行処理を表すものです ● 手続き実行ではなく、並列での関数の実行に使う事ができます ● ゴルーチンは呼び出し元の処理をブロックせずに実行されます main() 関数 ゴルーチン ゴルーチン ゴルーチン 並列処理 ゴルーチンとは

Slide 48

Slide 48 text

並列処理 ゴルーチン 48 ゴルーチンの使い方 実行方法 ● 関数/無名関数を扱える ● 呼出元の処理をブロックしない

Slide 49

Slide 49 text

並列処理 ゴルーチン 49 ゴルーチンの処理順序 実行内容

Slide 50

Slide 50 text

並列処理 ゴルーチン 50 ゴルーチンの処理順序 実行結果

Slide 51

Slide 51 text

並列処理 ゴルーチン 51 main() 関数が終了すると、実行中の全てのゴルーチンを中断します ※実行中のゴルーチンがあっても、完了を待ちません メインゴルーチンの処理を ブロックせずに実行 ※実行順序は保証されない main() 関数 (メインゴルーチン) go func (ゴルーチン) go func (ゴルーチン) go func (ゴルーチン)

Slide 52

Slide 52 text

並列処理 チャネル channels

Slide 53

Slide 53 text

並列処理 チャネル 53 チャネルとは ● チャネルはゴルーチン間のメッセージのやり取りをするものです ● メッセージは型を指定できます ● チャネルは容量 / 送信 / 受信 / クローズで構成されています

Slide 54

Slide 54 text

並列処理 チャネル 54 チャネルの使い方 実行方法

Slide 55

Slide 55 text

並列処理 チャネル 55 チャネルのキャパシティ ● チャネルにはキャパシティ(容量)があります ● チャネルのキャパシティは送信された値を保管できる容量です ● 受信側が待機している場合は、バッファは使用されません ● 容量が足りなくなると、チャネルへの送信はブロックされます

Slide 56

Slide 56 text

並列処理 ゴルーチン 56 ゴルーチンの使い方 実行方法 ● 関数/無名関数を扱える ● 呼出元の処理をブロックしない

Slide 57

Slide 57 text

並列処理 チャネル 57 送信チャネルのブロック サンプルコード

Slide 58

Slide 58 text

並列処理 チャネル 58 チャネルバッファを使わない送受信 サンプルコード

Slide 59

Slide 59 text

並列処理 チャネル 59 チャネルバッファを使った送信 サンプルコード

Slide 60

Slide 60 text

並列処理 チャネル 60 並列処理の完了を検知する ● 並列処理の完了を検知したい時、チャネルは有効です ● チャネルは使い方によっては問題を起こしてしまう事もあります ● 以下の例では受信側が処理の完了を待ち続けてしまいます

Slide 61

Slide 61 text

並列処理 チャネル 61 サンプルコード 完了検知のアンチパターン

Slide 62

Slide 62 text

並列処理 チャネル 62 サンプルコード deferとcloseで完了を検知する

Slide 63

Slide 63 text

コーディング規約 coding standards

Slide 64

Slide 64 text

コーディング規約 64 コード整形とコードスタイル ● Go言語は標準のgofmtを使ってコード整形をサポートしています ● Go言語の実装コードで挙がったレビューコメントが公開されています ● これらを厳密に守る必要はないですが、コードスタイルに悩んだ時の 参考にできます https://qiita.com/knsh14/items/8b73b31822c109d4c497

Slide 65

Slide 65 text

ユニットテスト unit tests

Slide 66

Slide 66 text

ユニットテスト 66 標準パッケージによるユニットテスト ● Go言語は標準のtestingパッケージでユニットテスト、ベンチマーク テストをサポートしています ● _test.goをつけて、テストとして実行します

Slide 67

Slide 67 text

ユニットテスト 67 テスト対象 サンプルコード

Slide 68

Slide 68 text

ユニットテスト 68 ユニットテストコード サンプルコード テストとして実行する場合はTestから始まる関数名にする

Slide 69

Slide 69 text

ユニットテスト 69 ● 実際に上記のテストを実行してみましょう ● go testで実行ができます ● go test -vで詳細な実行結果を出力する事もできます ● go test -coverでコードカバレッジも出力する事もできます テストの実行

Slide 70

Slide 70 text

ユニットテスト 70 テストの実行 実行結果

Slide 71

Slide 71 text

課題 20:20 ~ 21:20 ( 60 min )

Slide 72

Slide 72 text

目次 72 じゃんけんシミュレーターを作ろう 会話ゲームを作ろう 本日の課題

Slide 73

Slide 73 text

課題1 73 基本問題 ● グー、チョキ、パーからランダムで1つを出す2CPを作りましょう ● 結果は勝ち、負け、あいこのどれかです ● ゴルーチンやチャネルを使う必要はありません ● 100万回試行して、勝敗をカウントして表示しましょう 発展問題 ● 片方のCPを50%の確率でパーを出すように設定して、実行しましょう じゃんけんシミュレーターを作ろう

Slide 74

Slide 74 text

課題1 74 実行結果の例 じゃんけんシミュレーターを作ろう 勝利=340000回 引分=330000回 敗北=300000回 ------------------------ 合計=1000000回

Slide 75

Slide 75 text

課題2 75 会話ゲームを作ろう 基本問題 ● ゴルーチンとチャネルを使って、関数同士で会話をさせましょう ● 登場人物は2人です ● 各発言はそれぞれの名前がついた関数から発言します 発展問題 ● 登場人物を3人に増やしましょう

Slide 76

Slide 76 text

課題2 76 実行結果の例 会話ゲームを作ろう kent: あなたの名前を教えてください yukpiz: 私はゆくぴずです kent: 私はけんとです yukpiz: よろしくおねがいします kent: 生ハム食べに行きましょう yukpiz: 行きましょう

Slide 77

Slide 77 text

課題解答 77 解答時間のご案内 ● 解答時間は 21:20 までの 50分間 です ● 質問がある場合はスタッフにお声がけください ○ 挙手いただけばスタッフが伺います ○ Slackチャンネルで質問いただけば回答します ● 解答時間中は自由にご飲食・ご休憩ください ● 体調不良等ございましたらスタッフまでお申し付けください

Slide 78

Slide 78 text

最後に 21:20 ~ 21:30 ( 10 min )

Slide 79

Slide 79 text

解答について 79 解答例は以下URLよりご覧ください https://qiita.com/yukpiz/items/ef15557de423a2ccb230 ハンズオン後のサポートについて 閉会後に引き続きご質問がある場合、Slackでサポートします 以下のワークスペースにジョインし、#support-201811チャンネルでお気軽にご質問ください bit.ly/techdo-slack

Slide 80

Slide 80 text

次回開催予定のご案内 80 さらに進化した初心者向けハンズオンがここに・・! 2019年2月上旬頃(予定) また次回もご参加ください! https://techdo.connpass.com ※詳細が決まり次第、TwitterやConnpassグループ等で告知します

Slide 81

Slide 81 text

The Go gopher was designed by Renée French.

Slide 82

Slide 82 text

#4b4b4b #007ab7 #b61972 #4b4b4b #4b4b4b あいうえおかきくけこさしすせそ #007ab7 あいうえおかきくけこさしすせそ #b61972 あいうえおかきくけこさしすせそ Go Hands-on #2