SlideShare a Scribd company logo
1 of 131
Download to read offline
Go入門
ver. 2017/04
The Go gopher was designed by Renee French.
The gopher stickers was made by Takuya Ueda.
Licensed under the Creative Commons 3.0
Attributions license.
アジェンダ
■ 自己紹介
■ Goの紹介
■ Goの基本
■ 型・メソッド・インタフェース
■ ゴールーチン・チャネル
■ ネットワークプログラミング
■ go test と testingパッケージ
■ ハンズオン
2
自己紹介
上田拓也
twitter: @tenntenn
■ コミュニティ活動
Google Cloud Platform User Group (GCPUG) Tokyo
Goビギナーズ
golang.tokyo
Go Conference
3
Goの紹介
● Goとは?
● Goの特徴
● Goを勉強するには?
4
Goとは?
Googleが開発しているプログラミング言語
■ 特徴
● シングルバイナリ・クロスコンパイル
● 強力でシンプルな言語設計と文法
● 並行プログラミング
● 豊富な標準ライブラリ群
● 周辺ツールの充実
Goの紹介/Goとは?
5
Goの特徴 − シングルバイナリ・クロスコンパイル −
■ 環境変数のGOOSとGOARCHを指定する
開発環境とは違うOSやアーキテクチャ向けに
クロスコンパイルできる
Goの紹介/Goの特徴 − シングルバイナリ・クロスコンパイル −
6
# Windows(32ビット)向けにコンパイル
$ GOOS=windows GOARCH=386 go build
# Linux(64ビット)向けにコンパイル
$ GOOS=linux GOARCH=amd64 go build
シングルバイナリになるので
動作環境を用意しなくてよい
go buildはコンパイルするコマンド
Goの特徴 − 強力でシンプルな言語設計と文法 −
■ スクリプト言語の書きやすさ
● 冗長な記述は必要ない
■ 型のある言語の厳密さ
● 曖昧な記述はできない
■ 考えられたシンプルさ
● 機能を増やすことで言語を拡張していくこと
はしない
Goの紹介/Goの特徴 − 強力でシンプルな言語設計と文法 −
7
Goに入ってはGoに従え
= 言語の思想を理解しよう
Goの特徴 − 並行プログラミング −
■ ゴールーチン
● 軽量なスレッドに近いもの
● goキーワードをつけて関数呼び出し
■ チャネル
● ゴールーチン間のデータのやり取り
● 安全にデータをやり取りできる
Goの紹介/Goの特徴 − 並行プログラミング −
8
チャネル
ゴールーチン
A
ゴールーチン
B
データ
データ
go f()
Goの特徴 − 周辺ツールの充実 −
■ go tool として標準/準標準で提供
■ サードパーティ製のツールも充実
■ IDEによらない独立したツールとして提供
Goの紹介/Goの特徴 − 周辺ツールの充実 −
9
go build ビルドを行うコマンド
go test
xxxx_test.goに書かれたテスト
コードの実行
go doc, godoc ドキュメント生成
gofmt, goimports コードフォーマッター
golint コードチェッカー、リンター
gocode コード補完
Goの特徴 − 豊富な標準ライブラリ −
■ 標準ライブラリ一覧
 https://golang.org/pkg/
Goの紹介/Goの特徴 − 豊富な標準ライブラリ −
10
net/http HTTPサーバなど
archive, compress zipやgzipなど
crypto 暗号化
encoding JSON, XML, CSVなど
html/template HTMLテンプレート
os, path/filepath ファイル操作など
Goの勉強するには?
■ コミュニティ
● gophers-slack
○ 世界中のGopherが集まるチャット
● Qiita #Go
○ Go言語の初心者が見ると幸せになれる場所
■ 書籍
● The Go Programing Language(日本語)
● みんなのGo言語
Goの紹介/Goの勉強するには?
11
Goの基本
● A Tour of Goをやろう
● for, if, switch
● Goのインストール
● GOPATH
● go tool
12
A Tour of Goをやろう
■ A Tour of Go
● Goのチュートリアル
● Web上で実行できる
● Basicsにチャレンジしてみよう
Goの基本/A Tour of Goをやろう
13
繰り返し:for
■ Goの繰り返しはforのみ
Goの基本/繰り返しfor
14
// いつものfor
for i := 0; i <= 100; i++ {
}
// while的な使い方
for i <= 100 {
}
// 無限ループ
for {
}
()はいらない
分岐:if
■ 条件式の前に代入文などが書ける
Goの基本/分岐:if
15
// いつものif
if a == 0 {
}
// 代入文を書く
if a := f(); a > 0 {
fmt.Println(a)
} else {
fmt.Println(2*a)
}
()はいらない
分岐:switch
■ caseに式が書ける
■ breakは書かなくてよい
Goの基本/分岐:switch
16
switch a {
case 1:
fmt.Println("a is 1")
default:
fmt.Println("default")
}
swtich {
case a == 1:
fmt.Println("a is 1")
}
caseをまたぐ際には、
fallthroughを使う
何もしないと
breakになる
Goのインストール
■ インストール方法
 Goの公式サイトからダウンロード
■ ソースコードからビルドする
 Goの公式サイトを参考にする。
Goの基本/Goのインストール
17
Go1.5以上はビルドにGoが必要
そのため1.4のバイナリを入れておく
GOPATH
■ GOPATHとは?
 Goのソースコードやビルドされたファイルが入るパス。
importされるパッケージもここから検索される。
Goの基本/GOPATH
18
$GOPATH
├── bin
│ └── fuga
├── pkg
│ └── darwin_amd64
│ └── hoge.a
└── src
├── fuga
│ └── main.go
└── hoge
└── hoge.go
ビルドされた実行可能ファイルが入る
ビルドされたパッケージが入る。
pkg/GOARCH/pkgname.a
mainパッケージのGoソース。
src/cmdname/*.go
自作パッケージのGoソース。
src/pkgname/*.go
go tool − go install −
■ go install
 ビルドして、GOPATH以下に配置するコマンド。
Goの基本/go tool − go install −
19
$ export GOPATH=`pwd`
$ go install fuga
$GOPATH
├── bin
│ └── fuga
├── pkg
│ └── darwin_amd64
│ └── hoge.a
└── src
├── fuga
│ └── main.go
└── hoge
└── hoge.go
go install によって生成されたファイル
手元で試してみよう!
(src/fugaとsrc/hogeだけを使用)
go tool − go get −
■ go get
 パッケージをダウンロードしてビルドしてGOPATH以下に配置
するコマンド。
Goの基本/go tool − go install −
20
$ export GOPATH=`pwd`
$ go get github.com/nsf/termbox-go
└── src
└── github.com
├── mattn
│ └── go-runewidth
│ ...
│ └── runewidth_windows.go
└── nsf
└── termbox-go
...
└── terminfo_builtin.go
依存するパッケージも
インストールされる
.
├── pkg
│ └── darwin_amd64
│ └── github.com
│ ├── mattn
│ │ └── go-runewidth.a
│ └── nsf
│ └── termbox-go.a
手元で試してみよう!
型・メソッド・インタフェース
● 型の種類
● 配列・スライス・マップ・構造体
● type
● メソッド・インタフェース
● 埋め込み
21
型の種類
型・メソッド・インタフェース/型の種類
22
組み込み型 int, float64, string など
配列
[100]int など
要素の型と要素数は固定
スライス
[]int など
要素の型、要素数は可変。
マップ
map[string]int など
連想配列。
構造体
struct { a int } など
フィールドのリストを持つ
インタフェース
interface { m() int } など
メソッドのリストを持つ
配列 −1−
[要素数]要素の型
型・メソッド・インタフェース/配列 −1−
23
var a [3]int
a[1] = 10
b := [...]int{1, 2, 3}
for i, n := range b {
fmt.Println(i,"/",len(b),"=>", n)
}
Playgroundで動かす
要素数が違えば別の型
...で初期値の要素に合わせる
添字と値で繰り返せる
配列 −2−
値でコピーされる
型・メソッド・インタフェース/配列 −2−
24
a := [3]int{1, 2, 3}
b := a
a[0] = 10
for i := range a {
fmt.Println(a[i], b[i])
}
参照がコピーされる
わけではない
10, 1
2, 2
3, 3
関数に渡した場合も
同様に値がコピーされる
Playgroundで動かす
2つ目は省略可
スライス −1−
[]要素の型
make([]要素の型, 要素数[, キャパシティ])
型・メソッド・インタフェース/スライス −1−
25
a := make([]int, 3, 10)
fmt.Println(a, len(a), cap(a))
b := []int{1, 2, 3}
for i, n := range b {
fmt.Println(i,"/",len(b),"=>", n)
}
Playgroundで動かす
スライスでもrangeは使える
スライス −2−
スライスの背後には配列がある
型・メソッド・インタフェース/スライス −2−
26
a := [...]int{1, 2, 3, 4}
b := a[1:3]
fmt.Println(b, len(b), cap(b))
Playgroundで動かす
1 2 3 4
a[0] a[1] a[2] a[3]
b[0] b[1]
len(b) = 2
cap(b) = 3配列
スライス
スライス −3−
append(スライス, 要素...) スライス
型・メソッド・インタフェース/スライス −3−
27
var a []int // nil
for i := 0; i <= 10; i++ {
a = append(a, i * 10)
fmt.Println(len(a), cap(a), a)
}
Playgroundで動かす
appendした際にcapを
超えた場合は
新しく配列が確保される
スライス −4−
■ 課題1
配列とスライスをそれぞれ関数の引数や戻り値に
した場合の挙動の違いを考えてみよう。
■ 課題2
スライスへの任意位置への挿入、削除を実装して
みよう。
型・メソッド・インタフェース/スライス −4−
28
// スライスaとbを結合
c := append(a, b...)
Playgroundで動かす
可変長引数に
スライスを展開
マップ
map[キーの型]値の型
make(map[キーの型]値の型[, キャパシティ])
型・メソッド・インタフェース/マップ
29
a := make(map[string]int)
a["c"] = 100
n, ok := a["c"]
fmt.Println(n, ok)
b := map[string]int{"c":2, "d":4}
for k, v := range b {
fmt.Println(k, v)
}
Playgroundで動かす
値が存在すればnはその値、okはtrue
存在しなければ、nはゼロ値、okはfalse
キーと値で繰り返せる
構造体
フィールドのリストを持つデータ構造。
フィールドの型は任意の型を指定できる。
構造体のゼロ値は、フィールドすべてがゼロ値の構造体。
型・メソッド・インタフェース/構造体
30
a := struct{
N int
s string
}{
N: 100,
s: "hoge",
}
fmt.Printf("%#vn", a)
fmt.Println(a.N, a.s)
Playgroundで動かす
構造体リテラル
型情報
フィールド
typeを使った型の作成
type <型名> <型リテラル>|<既存の型>
型・メソッド・インタフェース/typeを使った型の作成
31
// 組み込み型に名前をつける
type Int int
// 他のパッケージの型に名前をつける
type MyWriter io.Writer
// 型リテラルに名前をつける
type Person struct {
Name string
}
intとIntは別の型として扱われる
typeで名前が付けれるもの
■ 組み込み型
int, float64, string など
■ 型リテラル
構造体、インタフェース、
マップ、スライス、チャネル、関数 など
■ 名前付きの型
パッケージの内外で作った型
型・メソッド・インタフェース/typeで名前を付けれるもの
32
別の型として再定義できる
メソッド −1−
type で定義した型はメソッドのレシーバにできる
型・メソッド・インタフェース/メソッド −1−
33
type Hex int
func (h Hex) String() string {
return fmt.Sprintf("%x", int(h))
}
// 100をHex型として代入
var hex Hex = 100
// Stringメソッドを呼び出す
fmt.Println(hex.String())
Playgroundで動かす
メソッド −2−
■ レシーバにできるもの
● 名前の付いた型
typeで定義したもの
● パッケージ内の型のみ
パッケージ外の型はtypeで再定義する
● ポインタ型も含む
レシーバに変更を与えたい場合
レシーバも引数と同じ扱い
型・メソッド・インタフェース/メソッド −2−
34
type Hex int など
type S bufio.Scanner
など
func (p *Hoge) M() {
...
} など
メソッド −3−
■ 課題3
関数にメソッドを設けてみよう。
var f func(string) int
■ 課題4
レシーバをポインタにしてみてレシーバに変更を与
えてみよう。構造体以外も試してみよう。
■ 課題5
レシーバがnilの場合の挙動を試してみよう。
型・メソッド・インタフェース/メソッド −3−
35
インタフェース
● メソッドのリストを持つ
● メソッドのリストがインタフェースで規定しているものと一致
する型はインタフェースを実装していることになる
型・メソッド・インタフェース/インタフェース
36
var s interface {
String() string
}
s = Hex(100)
fmt.Println(s.String())
type Hex int
func (h Hex) String() string {
return fmt.Sprintf("%x", int(h))
}
Playgroundで動かす
インタフェースを実装していることになる
型とメソッドとインタフェース
■ 既存の型にもインタフェースを実装
● 後づけで実装させる
● メソッドリストさえ一致してればよい
■ 構造体以外も実装可能
● typeで宣言すればメソッドが設けられる
● メソッドリストさえ一致してればよい
型・メソッド・インタフェース/型とメソッドとインタフェース
37
インタフェースの活用
■ 1つのメソッドしか持たない
● io.Writer: Writeメソッド
● io.Reader: Readメソッド
■ 標準パッケージで多く使われている
● fmt, net, bytes, encoding, bufio, os ...
● ファイルやネットワークのコネクション
● 抽象度の高いインタフェース
型・メソッド・インタフェース/インタフェースの活用
38
インタフェースは
Goの良い言語機能の1つ
インタフェース
■ 課題6
interface{} という型はどういう特徴を持つ型
か説明してください。
■ 課題7
インタフェース型を1つ作り、組み込み型、構造体
型、関数型にそれぞれ実装させてみましょう。ま
た、作ったインタフェース型を引数に取る関数を
作ってみましょう。
型・メソッド・インタフェース/インタフェース
39
型アサーション
インタフェース.(型)
インタフェース型の値を任意の型にキャストする。第2戻り値に
キャストできるかどうかが返る。
型・メソッド・インタフェース/型アサーション
40
var v interface{}
v = 100
n,ok := v.(int)
fmt.Println(n, ok)
s,ok := v.(string)
fmt.Println(s, ok)
Playgroundで動かす
型スイッチ
型によって処理をスイッチする
型・メソッド・インタフェース/型スイッチ
41
var i interface{}
i = 100
switch v := i.(type) {
case int:
fmt.Println(v*2)
case string:
fmt.Println(v+"hoge")
default:
fmt.Println("default")
}
Playgroundで動かす
インタフェース
i = "hoge"
も試してみよう
埋め込み −1−
構造体に匿名フィールドを埋め込む機能
型・メソッド・インタフェース/埋め込み −1−
42
type Hoge struct {
N int
}
// Fuga型にHoge型を埋め込む
type Fuga struct {
Hoge // 名前のないフィールドになる
}
埋め込み −2−
埋め込んだ値に移譲(継承とは違う)
型・メソッド・インタフェース/埋め込み −2−
43
type Hoge struct {N int}
type Fuga struct {Hoge}
f := Fuga{Hoge{N:100}}
// Hoge型のフィールドにアクセスできる
fmt.Println(f.N)
// 型名を指定してアクセスできる
fmt.Println(f.Hoge.N)
Playgroundで動かす
埋め込みの特徴
■ 型リテラルでなければ埋め込められる
● typeで定義したものや組み込み型
● インタフェースも埋め込められる
■ インタフェースの実装
埋め込んだ値のメソッドもカウント
型・メソッド・インタフェース/埋め込みの特徴
44
// Stringerを実装
type Hex int
func (h Hex) String() string {
return fmt.Sprintf("%x", int(h))
}
// Hex2もStringerを実装
type Hex2 struct {Hex}
type Stringer interface {
String() string
}
Playgroundで動かす
インタフェースと埋め込み
■ 既存のインタフェースの振る舞いを変える
型・メソッド・インタフェース/インタフェースと埋め込み
45
type Hoge interface{M();N()}
type fuga struct {Hoge}
func (f fuga) M() {
fmt.Println("Hi")
f.Hoge.M() // 元のメソッドを呼ぶ
}
func HiHoge(h Hoge) Hoge {
return fuga{h} // 構造体作る
}
Mの振る舞いを変える
インタフェースと埋め込み
■ 課題8
以下のコードは有効でしょうか?Playgroundで動
かして確認しましょう。
■ 課題9
前のスライドの例を実際にPlaygroundで動かして
挙動を確認しよう。
型・メソッド・インタフェース/インタフェースと埋め込み
46
type Hoge struct {N int}
type Fuga struct {Hoge}
f := Fuga{Hoge{100}}
var _ Hoge = f _は変数を使用しないときに使う記法
HiHogeの戻り値の型が
Hogeにできる理由は?
参考:インタフェースの実装パターン
ゴールーチン・チャネル
● 並行と並列
● ゴールーチン
● チャネル
● チャネルを使うパターン
47
Concurrency is not Parallelism
■ 並行と並列は別ものである by RobPike
● 並行:Concurrency
● 並列:Parallelism
■ Concurrency
● 同時にいくつかの質の異なることを扱う
■ Parallelism
● 同時にいくつかの質の同じことを扱う
ゴールーチン・チャネル/Concurrency is not Parallelism
48
並列と並行の違い
■ Concurrency
 同時にいくつかの質の異なることを扱う
■ Parallelism
 同時にいくつかの質の同じことを扱う
ゴールーチン・チャネル/並行と並列の違い
49
本を運ぶ
本を燃やす
台車を戻す
本を積む
本を燃やす 本を燃やす 本を燃やす
ゴールーチンとConcurrency
■ ゴールーチンでConcurrencyを実現
● 複数のゴールーチンで同時に複数のタスクをこなす
● 各ゴールーチンに役割を与えて分業する
■ 軽量なスレッドのようなもの
● LinuxやUnixのスレッドよりコストが低い
● 1つのスレッドの上で複数のゴールーチンが動く
■ ゴールーチンの作り方
● goキーワードをつけて関数を呼び出す
ゴールーチン・チャネル/ゴールーチンとConcurrency
50
複数のコアで動くとは限らない
go f()
無名関数とゴールーチン
ゴールーチン・チャネル/無名関数とゴールーチン
51
package main
import "fmt"
import "time"
func main() {
go func() {
fmt.Println("別のゴールーチン")
}()
fmt.Println("mainゴールーチン")
time.Sleep(50*time.Millisecond)
}
Sleepしないとすぐに終了する
http://play.golang.org/p/jy1HWriRTS
ゴールーチン間のデータのやりとり −1−
ゴールーチン・チャネル/ゴールーチン間のデータのやりとり −1−
52
ゴールーチン-main
ゴールーチン-2
go f2()
ゴールーチン-1
go f1()
ゴールーチン間のデータのやりとり −2−
ゴールーチン・チャネル/ゴールーチン間のデータのやりとり −2−
53
ゴールーチン-main
ゴールーチン-2
go f2()
ゴールーチン-1
go f1()
変数v
print(v) v = 100
共有の変数を使う?
ゴールーチン間で共有の変数を使う
ゴールーチン・チャネル/ゴールーチン間で共有の変数を使う
54
func main() {
done := false
go func() {
time.Sleep(3 * time.Second)
done = true
}()
for !done {
time.Sleep(time.Millisecond)
}
fmt.Println("done!")
}
共有の変数を使う
http://play.golang.org/p/mGSOaq4mcr
ゴールーチン間のデータ競合 −1−
ゴールーチン・チャネル/ゴールーチン間のデータ競合 −1−
55
ゴールーチン-main
ゴールーチン-2
go f2()
ゴールーチン-1
go f1()
変数v
print(v) v = 100
処理順序が保証されない
競合
ゴールーチン間のデータ競合 −2−
ゴールーチン・チャネル/ゴールーチン間のデータ競合 −2−
56
n := 1
go func() {
for i := 2; i <= 5; i++ {
fmt.Println(n, "*", i)
n *= i
time.Sleep(100)
}
}()
http://play.golang.org/p/yqk82u0E4V
for i := 1; i <= 10; i++ {
fmt.Println(n, "+", i)
n += 1
time.Sleep(100)
}
競合
データ競合の解決
■ 問題点
● どのゴールーチンが先にアクセスするか分からない
● 値の変更や参照が競合する
■ 解決方法
● 1つの変数には1つのゴールーチンからアクセスする
● チャネルを使ってゴールーチン間で通信をする
● またはロックをとる(syncパッケージ)
ゴールーチン・チャネル/データ競合の解決
57
"Do not communicate by sharing memory; instead,
share memory by communicating"
チャネルとは?
ゴールーチン・チャネル/チャネルとは?
58
ゴールーチン-main
ゴールーチン-2
go f2()
ゴールーチン-1
go f1()
ch<-100<-ch
チャネル
100
チャネルの特徴
■ 送受信できる型
● チャネルを定義する際に型を指定する
■ バッファ
● チャネルにバッファを持たせることができる
● 初期化時に指定できる
● 指定しないと容量0となる
■ 送受信時の処理のブロック
● 送信時にチャネルのバッファが一杯だとブロック
● 受信時にチャネル内が空だとブロック
ゴールーチン・チャネル/チャネルの特徴
59
送信時のブロック
ゴールーチン・チャネル/送信時のブロック
60
ゴールーチン-main
ゴールーチン-2
go f2()
ゴールーチン-1
go f1()
受信してくれるまでブロック
ch<-100
チャネル
100
ブロック
受信時のブロック
ゴールーチン・チャネル/受信時のブロック
61
ゴールーチン-main
ゴールーチン-2
go f2()
ゴールーチン-1
go f1()
送信されるまでブロック
<-ch
チャネル
100
ブロック
チャネルの基本 −1−
ゴールーチン・チャネル/チャネルの基本 −1−
62
■ 初期化
■ 送信
■ 受信
ch1 := make(chan int)
ch2 := make(chan int, 10)
n1 := <-ch1
n2 := <-ch2 + 100
容量を指定
ch1 <- 10
ch2 <- 10 + 20
受け取られるまでブロック
一杯であればブロック
送信されまでブロック
空であればブロック
make(chan int, 0)と同じ
チャネルの基本 −2−
ゴールーチン・チャネル/チャネルの基本 −2−
63
func main() {
done := make(chan bool) // 容量0
go func() {
time.Sleep(time.Second * 3)
done <- true
}()
<-done
fmt.Println("done")
}
送信されるまでブロック
http://play.golang.org/p/k0sMCYe4PA
複数のチャネルから同時に受信
ゴールーチン・チャネル/複数のチャネルから同時に受信
64
ゴールーチン-main
ゴールーチン-2
go f2()
ゴールーチン-1
go f1()
チャネル-1 チャネル-2
ブロック
ブロックされるので
同時に送受信出来ない?
select - case −1−
ゴールーチン・チャネル/select-case −1−
65
ゴールーチン-main
ゴールーチン-2
go f2()
ゴールーチン-1
go f1()
チャネル-1 チャネル-2
ブロックされるので
同時に送受信出来ない?
select
select - case −2−
ゴールーチン・チャネル/select - case −2−
66
func main() {
ch1 := make(chan int)
ch2 := make(chan string)
go func() { ch1<-100 }()
go func() { ch2<-"hi" }()
select {
case v1 := <-ch1:
fmt.Println(v1)
case v2 := <-ch2:
fmt.Println(v2)
}
}
先に受信した方を処理
http://play.golang.org/p/moVwtEdQIv
nilチャネル
ゴールーチン・チャネル/nilチャネル
67
func main() {
ch1 := make(chan int)
var ch2 chan string
go func() { ch1<-100 }()
go func() { ch2<-"hi" }()
select {
case v1 := <-ch1:
fmt.Println(v1)
case v2 := <-ch2:
fmt.Println(v2)
}
}
nilの場合は無視される
ゼロ値はnil
http://play.golang.org/p/UcqW6WH0XT
ファーストクラスオブジェクト
■ チャネルはファーストクラスオブジェクト
● 変数に入れれる
● 引数に渡す
● 戻り値で返す
● チャネルのチャネル
■ timeパッケージ
ゴールーチン・チャネル/ファーストクラスオブジェクト
68
http://golang.org/pkg/time/#After
chan chan int など
// 5分間待つ
<-time.After(5 * time.Minute)
5分たったら現在時刻が
送られてくるチャネルを返す
チャネルを引数や戻り値にする
ゴールーチン・チャネル/チャネルを引数や戻り値にする
69
func makeCh() chan int {
return make(chan int)
}
func recvCh(recv chan int) int {
return <-recv
}
func main() {
ch := makeCh()
go func() { ch <- 100 }
fmt.Println(recvCh(ch))
}
http://play.golang.org/p/UcqW6WH0XT
双方向チャネル
ゴールーチン・チャネル/双方向チャネル
70
func makeCh() chan int {
return make(chan int)
}
func recvCh(recv chan int) int {
go func() { recv <- 200 }()
return <-recv
}
func main() {
ch := makeCh()
go func() { ch <- 100 }()
fmt.Println(recvCh(ch))
}
http://play.golang.org/p/6gU92C6Q2v
間違った使い方ができる
単方向チャネル
ゴールーチン・チャネル/単方向チャネル
71
func makeCh() chan int {
return make(chan int)
}
func recvCh(recv <-chan int) int {
return <-recv
}
func main() {
ch := makeCh()
go func(ch chan<- int) {
ch <- 100
}(ch)
fmt.Println(recvCh(ch))
}
http://play.golang.org/p/pY4u1PU3SU
受信専用のチャネル
送信専用のチャネル
タイピングゲーム
■ 課題10
90秒以内に予め用意された5つの文章を入力させ、すべて入力
できた場合は"OK"と出力し、タイムオーバーの場合は"Time
Over"と表示するプログラムを作ってください。なお、入力ミスし
た場合は正解するまで同じ文章を入力させてください。
ヒント:
time.After, bufio.Scanner
ゴールーチン・チャネル/タイピングゲーム
72
Concurrencyの実現
■ 複数のゴールーチンで分業する
● タスクの種類によってゴールーチンを作る
● Concurrencyを実現
■ チャネルでやりとりする
● ゴールーチン間はチャネルで値を共有する
● 複雑すぎる場合はロックを使うことも
■ for-selectパターン
● ゴールーチンごとに無限ループを作る
● メインのゴールーチンはselectで結果を受信
ゴールーチン・チャネル/Concurrencyの実現
73
for-selectパターン −1−
ゴールーチン・チャネル/for-selectパターン −1−
74
ゴールーチン-main
ゴールーチン-2
go f2()
ゴールーチン-1
go f1()
チャネル-1 チャネル-2
select
for{}for{}
各ゴールーチンで
無限ループを作る
for-selectパターン −2−
ゴールーチン・チャネル/for-selectパターン −2−
75
ゴルーチン-1
for{}
ゴルーチン-2
for{}
ゴルーチン-3
for{}
ゴルーチン-4
for{}
チャネル
チャネル
チャネル
チャネル
GopherでConcurrency
■ 課題11
前のスライドのGopherたちが本を燃やす様子をプログラムで表
現してみてください。なお、1冊の本を燃やしたり、本を積んだ
り、台車を運んだりするのに、それなりに時間がかかることを想
定し、適度にtime.Sleepで処理を止めて見ましょう。
■ 課題12
課題11で燃やす本の量をどんどん増やした場合に、どうス
ケールすれば処理速度を落とさずに本を燃やせるでしょうか?
ゴールーチン・チャネル/GopherでConcurrency
76
# データ競合のチェック
go run -race main.go
ネットワークプログラミング
● netパッケージ
● net/httpパッケージ
77
netパッケージ −サーバ−
ネットワークプログラミング/netパッケージ −サーバー−
78
p, a := "tcp", ":8080"
ln, err := net.Listen(p, a)
if err != nil {...}
for {
conn, err := ln.Accept()
if err != nil {...}
go handle(conn)
}
エラー処理
エラー処理
netパッケージ −クライアント−
ネットワークプログラミング/netパッケージ −クライアント−
79
p, a := "tcp", ":8080"
conn, err := net.Dial(p, a)
if err != nil {...}
// 書き込み
fmt.Fprintln(conn, "hello")
エラー処理
手元で試してみよう!
(クライアント、サーバ)
グループチャットも
作ってみよう!
(プログラミング言語Goの8.10も参考になります。)
net/httpパッケージ
ネットワークプログラミング/net/httpパッケージ
80
h := func(
w http.ReponseWriter,
r *http.Request) {
fmt.Fprintf(w, "hello")
}
http.HandleFunc("/hello", h)
const a = ":8080"
http.ListenAndServe(a, nil)
手元で試してみよう!
Android上でサーバを動かす
81
ネットワークプログラミング/Android上でサーバを動かす
Youtubeで見る コード
母艦のシェル
adb shell
端末
タイピングゲーム2
■ 課題13
課題11のタイピングゲームを改造し、netパッケージを使って
立てたtcpのサーバから問題となる文章と制限時間を取得し、そ
の時間内にタイピングできるかを競うゲームにしてみよう。
■ 課題14
上記のプログラムをサーバとクライアントで実行可能ファイルを
分けずに、1つの実行ファイルでサーバもクライアントも実現しよ
う。また、問題の出題を交互に行えるようにしよう。
ネットワークプログラミング/タイピングゲーム2
82
go test とtestingパッケージ
● go test
● testingパッケージ
● コードの品質とGo
83
go test
go test と testingパッケージ/go test
84
■ testを行うためコマンド
 _testというサフィックスの付いた
 goファイルを対象にしてテストを実行
# mypkgのテスト行う
$ go test mypkg
ok mypkg 0.007s
# 失敗する場合
$ go test mypkg
--- FAIL: TestHex_String (0.00s)
hex_test.go:11: expect="a"
actual="A"
FAIL
FAIL mypkg 0.008s
hex.go ⇒ hex_test.go
go testのオプション(一部)
■ -v
詳細を表示する。
■ -cpu
実行する並列度を指定する。
複数のコアを使ったテストができる。
■ -race
データの競合が起きないかテストする。
■ -cover
カバレッジを取得する。
go test と testingパッケージ/go testのオプション(一部)
85
testingパッケージ
■ テストを行うため機能を提供するパッケージ
 *testing.T型のメソッド使う。
go test と testingパッケージ/testingパッケージ
86
package mypkg_test
import "testing"
import "mypkg"
func TestHex_String(t *testing.T) {
expect := "a"
actual := mypkg.Hex(10).String()
if actual != expect {
t.Errorf(`expect="%s" actual="%s"`, expect, actual)
}
}
type Hex int
func (h Hex) String() string {
return fmt.Sprintf("%x", int(h))
}
mypkg.go
mypkg_test.go
testingパッケージでできること
■ 失敗理由を出力してテストを失敗させる
 Error(), Errorf(),
 Fatal(), Fatalf()
■ テストの並列実行
Parallel()
go testの-parallelオプションで並列数を指定
■ ベンチマーク
 *testing.B型を使う
■ ブラックボックステスト
testing/quickパッケージ
go test と testingパッケージ/testingパッケージでできること
87
testingパッケージでできないこと
■ アサーションはない
自動でエラーメッセージを作るのではなく、
ひとつずつErrorfを使って自前で作る
■ テストはGoで書く
テストのための新しいミニ言語を作らない
■ 比較演算子だけはツライのでは?
reflect.DeepEqualを使うと良い
go test と testingパッケージ/testingパッケージでできないこと
88
かなり薄いテストパッケージ
Go Mock
■ インタフェースのモックを作るツール
github.com/golang/mock/gomock
メソッドが呼ばれているかなどがテストできる。
標準パッケージではなく、サブプロジェクト。
func TestSample(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
m := mock.NewMockSample(ctrl)
m.EXPECT().Method("hoge").Return(1)
t.Log("result:", m.Method("hoge"))
}
参考:Go Mockでインタフェースのモックを作ってテストする
go test と testingパッケージ/Go Mock
89
Goのコンセプト
■ 実現する手段は少ないほうが良い
 機能が増えると複雑さが増える。
■ 暗黙的で曖昧な記述をさせない
 エラーにつながる,暗黙の型変換や
 不使用の変数等の宣言は許さない。
■ 不要なものは避ける
 不要な型の宣言の排除など,
 タイプ数をできるだけ減らすように。
■ コンセプトに一貫性を持たせる
 コンセプトにずれる言語仕様は入れない。
go test と testingパッケージ/Goのコンセプト
90
“Simplicity is Complicated” by Rob Pike
シンプルさと強力さ
■ シンプルな機能を組み合わせる
 シンプルな機能を組み合わせて,複雑な問題に対処する
  ⇒シンプルだが強力さも十分ある
go test と testingパッケージ/シンプルさと強力さ
91
シンプル
簡潔さ
強力さ
表現力
品質の良いコードが作りやすい
Goのコード品質を高める要素
■ シンプルな文法と言語設計
 可読性の高い文法と複雑になりにくい言語仕様。
■ 型階層がない
 複雑な型の階層が存在せず不要な型ができにくい。
■ コンパイルによるエラー検出
 静的型付け言語なのでバグがコンパイル時に分かる。
 バグになり得る箇所がコンパイルエラーになる。
 (型不一致,未使用の変数など)
■ コードフォーマッタ
 標準のコードフォーマッタ(gofmt)がある。
■ テスト
 標準のテストツール(go test)がある
go test と testingパッケージ/Goのコード品質を高める要素
92
コンパイルエラーになるもの −1−
■ 型の不一致
go test と testingパッケージ/コンパイルエラーになるもの −1−
93
var n int = 100
var m float64 = 1.5
// エラー
var a int = n + m
// OK
var b int = n + int(m)
コンパイルエラーになるもの −2−
■ 未使用の変数/パッケージ
go test と testingパッケージ/コンパイルエラーになるもの −2−
94
import (
"fmt" // エラー
_ "io" // OK
)
func main() {
var n int = 100 // エラー
_ = 200 // OK
}
コンパイルエラーになるもの −3−
■ インタフェースの未実装(型の不一致)
go test と testingパッケージ/コンパイルエラーになるもの −3−
95
type Hex int
func (h Hex) Str() string {
return fmt.Sprintf("%x", int(h))
}
// エラー
var _ fmt.Stringer = Hex(100)
type Stringer
interface {
String() string
}
コンパイルエラーになるもの −4−
■ 曖昧な記述
go test と testingパッケージ/コンパイルエラーになるもの −4−
96
type Hoge struct{ N int }
type Piyo struct{ N int }
type Foo struct {
Hoge
Piyo
}
func main() {
f := Foo{Hoge{100}, Piyo{200}}
fmt.Println(f.N) // エラー
fmt.Println(f.Hoge.N) // OK
}
Goとテスト
■ 言語のコンセプトを守る
● 実現する手段は少なく
⇒ テストの為のミニ言語を入れない。
● 暗黙的で曖昧な記述をさせない
⇒ アサーションで自動でエラーメッセージを作らない。
 コンテキストにあったエラーメッセージを作る。
■ コンパイルエラーで検出できる
コンパイルで検出できるものはテストは不要。
コンパイルでは検出できないものに集中できる。
■ テストが良いサンプル
テストがGoで書かれてるので良いサンプルになる。
go test と testingパッケージ/Goとテスト
97
FAQを読もう!
ドキュメントとテスト
■ テストされたサンプル
func ExampleHex_String() {
fmt.Println(mypkg.Hex(10))
// Output: a
}
テストファイルにExampleで始まる
関数を書くとサンプルとして扱われる。
// Output:を書くとテスト対象になる。
go test と testingパッケージ/ドキュメントとテスト
98
言語標準ツールの強み
■ ツール間で連携が取りやすい
標準ツールなので、他のツールと連携が取りやすい
■ メンテが保証される
 バグが放置されたり、メンテされなかったりしない
■ みんなが共通に使う
その言語を使っているユーザ間で、共通の知識になる
テストツールも
言語標準のメリットは大きい
go test と testingパッケージ/言語標準ツールの強み
99
課題
■ 課題15
hogeパッケージのテスト書いてみましょう。
■ 課題16
Exapleテストを書いてみましょう。
また、godocを使ってドキュメント生成してみましょう。
go test と testingパッケージ/課題
100
# godocをインストールしよう
$ go get golang.org/x/tools/cmd/godoc
$ $GOPATH/bin/godoc --http=":8080"
リフレクション
● reflectパッケージとは
● リフレクションの基本
101
reflectパッケージとは?
■ 何ができるのか?
● 実行時に型情報を取得
● 任意の型の変数に値を入れる
● 構造体のフィールドのタグを取得する
■ どこで使われてるの?
● encodingパッケージ
● ORマッパーなど
リフレクション/reflectパッケージとは?
102
encodingパッケージでの利用
● JSONなどのシリアライズされたものを構造体に
変換する際に使用される
type Person struct {
Name string `json:"name"`
Aget int `json:"age"`
}
{
"name": "Gopher",
"age": 4
}
Goの構造体:
JSON例:
structタグで対応付ける
リフレクション/encodingパッケージでの利用
templateパッケージでの利用
● HTMLなどに任意の型の値を埋め込むために
使われる
Hello, {{.Name}}!! Hello, Gopher!!
Person {
Name: “Gopher”,
Age: 4,
}
テンプレート 出力
データの埋込み
Execute
リフレクション/templateパッケージでの利用
Value型とType型
■ Value型
● 任意の値を表す型
● 値への操作をメソッドで提供
● reflect.ValueOf()で取得できる
■ Type型
● 任意の型を表す型
● 型に関する操作をメソッドで提供
● reflect.TypeOf()で取得できる
105
リフレクション/Value型とType型
変数に値を入れる
106
var n int
fmt.Println(n) // 0
vp := reflect.ValueOf(&n)
v := vp.Elem()
if v.CanSet() {
v.SetInt(100)
}
fmt.Println(n) // 100
http://play.golang.org/p/HkJPjQsP8o
リフレクション/変数に値を入れる
変数に値を入れる(図解)
100n: &n
Value
(ポインタ)
ValueOf()
Value
(Int)
Elem()
Set
リフレクション/変数に値を入れる(図解)
interface{}としてポインタを渡す
■ interface{}として、任意の型のポインタを受
け取る
func set(p, v interface{}) {
pv := reflect.ValueOf(p) // ポインタ
vv := reflect.ValueOf(v) // 設定する値
pv.Elem().Set(vv)
}
リフレクション/interface{}としてポインタを渡す
構造体のリフレクション
109
s := struct{
A string `k:"v"`; b int
}{"a", 1}
v := reflect.ValueOf(&s).Elem()
println(v.FieldByName("A").CanSet())
println(v.FieldByName("b").CanSet())
f1, ok := v.Type().FieldByName("A")
println(ok, f1.PkgPath, f1.Tag.Get("k"))
f2, _ := v.Type().FieldByName("b")
println(f2.PkgPath)
http://play.golang.org/p/NkwP3KSjDu
リフレクション/構造体のリフレクション
リフレクションの注意点
■ 容易にpanicが起きる
● ValueとTypeで実体によって対応していな
いメソッドを呼ぶとpanicになる
○ 例:int型の値のValueに対してLen()を呼ぶ
● Kindで適切に分岐してpanicを避ける
■ 実行時間がかかる
● 実行時に解析するのでコストが大きい
● 静的解析を用いる選択肢もある
リフレクション/リフレクションの注意点
静的解析
● 静的解析とは?
● Goにおける静的解析
● 静的解析の基本
111
ソースコードの静的解析とは?
112
■ ソースコードを実行せずに解析すること
● ソースコードから抽象構文木(AST)などを取
得して解析する
● 静的型付け言語だと、静的解析で型情報が
取得できる
● 逆は実行して解析する動的解析
静的解析/ソースコードの静的解析とは?
Goで静的解析をすると何が嬉しいのか?
● リファクタリングツール
○ 変数の宣言位置や使用箇所の抽出
○ パッケージの解析
● コードジェネレーター
○ コメントによるアノテーションの抽出
○ コードフォーマッタ
● 処理系
○ 抽象構文木(AST)の解析
○ 定数の扱い
113
静的型付け言語なので
静的解析でも多くの事が知れる
静的解析/Goで静的解析をすると何が嬉しいのか?
開発ツールとソースコードの静的解析
114
■ 開発ツールの多くは静的解析を行っている
● gofmt/goimports
○ コードフォーマッター
● go vet/golint
○ コードチェッカー、リンター
● guru
○ 静的解析
● gocode
○ コード補完
● errcheck
○ エラー処理のチェック
● gorename/gomvpkg
○ リファクタリングツール
静的解析/開発ツールとソースコードの静的解析
■ 標準パッケージで静的解析の機能を提供
goパッケージ
115
go/ast 抽象構文木(AST)を提供
go/build パッケージに関する情報を集める
go/constant 定数に関する型を提供
go/doc ドキュメントをASTから取り出す
go/format コードフォーマッタの機能を提供
go/importer コンパイラに適したImporterを提供
go/parser 構文解析の機能を提供
go/printer ASTの表示機能を提供
go/scanner 字句解析の機能を提供
go/token トークンに関する型を提供
go/types 型チェックに関する機能を提供
静的解析/goパッケージ
静的解析の流れ
116
ソースコード
トークン
抽象構文木(AST)
型情報
構文解析
字句解析
型チェック
go/scanner
go/token
go/parser
go/ast
go/types
go/constant
静的解析/静的解析の流れ
字句解析 - go/scanner,go/token
■ 文字列をトークンにしていく
● 空白などを取り除き、意味のある単位=トー
クンにしていく作業
117
v + 1
IDENT ADD INT
トークン
ソースコード
静的解析/字句解析
構文解析 - go/parser,go/ast
■ トークンを抽象構文木(AST)にしていく
● プログラムの構造を持たせる
118
v + 1
IDENT ADD INT
ソースコード
+
v 1
BinaryExpr
Ident BasicLit
トークン
抽象構文木(AST)
静的解析/構文解析
型チェック - go/types,go/constant
■ 型チェックを行う
● 識別子の解決
● 型の推論
● 定数の評価
119
n := 100 + 200
fmt.Println(n)
定数の評価
=300
型の推論
-> int
識別子の解決
識別子の解決
-> fmtパッケージ
静的解析/型チェック
抽象構文木(ASt)の取得
■ go/parserパッケージの関数を使う
● ParseExpr,ParseExprFrom
○ 式をパースする
○ ParseExprはParseExprFromを簡易版
● ParseFile
○ ファイル単位でパースする
● ParseDir
○ ディレクトリ単位でパースする
○ 中でParseFileを呼んでいる
120
静的解析/抽象構文木(AST)の取得
式のASTを取得する
■ 式を構文解析する
■ ParseExprFromでも書ける
121
expr, err := parser.ParseExpr(`v + 1`)
if err != nil {
/* エラー処理 */
}
/* exprを解析する処理 */
fset := token.NewFileSet() // ファイル情報
src := []byte(`v + 1`)
f := "" // ファイル名(式なので不要)
m := 0 // モード(式なので不要)
expr, err := parser.ParseExprFrom(fset, f, s, m)
静的解析/式のASTを取得する
token.FileSetとは?
■ ファイル中の位置情報を記録する為の型
● 位置情報は数値で表される
● 複数のファイル間で一意の値
● 各ファイルのoffsetが記録されている
● パースする際に記録されていく
122
token.FileSetは出力引数として
Parse系の関数に渡す
静的解析/token.FileSetとは?
ファイルからASTを取得する
■ 完全なGoのソースコードを構文解析する
123
const src = `
package main
var v = 100
func main() {
fmt.Println(v+1)
}`
fs := token.NewFileSet()
f, err := parser.ParseFile(fs, "my.go", src, 0)
if err != nil {
/* エラー処理 */
}
/* f を解析する処理
引数はparse.ExprFromと
同じ構成
srcがnilだとファイル名
でファイルを開く
解析するファイルの中身
静的解析/ファイルからASTを取得する
Hello, WorldのASTの構成
124
package main
import "fmt"
func main() {
fmt.Println("Hello, 世界")
}
ast.File
ast.File
ast.GenDecl
ast.FuncDecl
ast.CallExpr
Goの抽象構文木(AST)を手入力してHello, Worldを作る
http://qiita.com/tenntenn/items/0cbc6f1f00dc579fcd8c
Playgroundで動かす
静的解析/Hello, WorldのASTの構成
ASTをトラバースする
■ ast.Inspectを使う
125
n, _ := parser.ParseExpr(`v + 1`)
ast.Inspect(n, func(n ast.Node) bool {
if n != nil { fmt.Printf("%Tn", n) }
return true
})
printer.Fprint(os.Stdout, token.NewFileSet(), n)
*ast.BinaryExpr
*ast.Ident
*ast.BasicLit
v + 1
+
v 1
構文解析
抽象構文木(AST)を探索
抽象構文木(AST)を出力
BinaryExpr
Ident BasicLit
Playgroundで動かす
ast.Walkというのもある
静的解析/ASTをトラバースする
ASTをトラバースする
■ 再帰を使ってトラバースする
126
func traverse(n ast.Node) {
switch n := n.(type) {
case *ast.Indent:
fmt.Println(n.Name)
case *ast.BinaryExpr:
traverse(n.X)
traverse(n.Y)
case *ast.UnaryExpr:
traverse(n.X)
}
}
識別子の場合は名前を出力
二項演算式の場合は
各項を探索
単項演算式の場合は
項を探索
型でswitchする
https://play.golang.org/p/5SOdiy420p
静的解析/ASTをトラバースする
参考資料
■ goパッケージで簡単に静的解析して世界を広げよう
● コードジェネレータ
○ ASTを取得する方法を調べる
○ 抽象構文木(AST)をトラバースする
○ 抽象構文木(AST)をいじってフォーマットをかける
○ Goの抽象構文木(AST)を手入力してHello, Worldを作る
○ go-app-builderのソースコードを読む
● リファクタリングツール
○ gorenameをライブラリとして使う
○ Goのスコープについて考えてみよう
○ go/typesパッケージを使い変数名をリネームしてみる
● 処理系
○ 簡単な式の評価機を作ってみる
○ 【実践goパッケージ】文字列から複素数型の値をパースする
○ もっと楽して式の評価器を作る
127
静的解析/参考資料
ハンズオン
● ハンズオンの説明
● ドキュメントとPlayground
128
ハンズオンの説明
■ リポジトリ
● https://github.com/tenntenn/gohandson/tree/master/i
mgconv/ja
■ コマンドラインツール
● ターミナルで動くプログラム
● 画像を変換するツール
# 50%に縮小して、JPEGにする
$ imgconv -resize 50% a.png b.jpg
ハンズオン/ハンズオンの説明
129
ドキュメントを読もう
■ パッケージドキュメント
● https://golang.org/pkg
● 標準パッケージの使い方が書いてある
■ FAQ
● https://golang.org/doc/faq
● なぜGoに◯◯がないのか?など
■ 言語仕様
● https://golang.org/ref/spec
公式ドキュメントを読もう!!
ハンズオン/ドキュメントを読もう
130
Go Playground
■ Go Playground
● http://play.golang.org/
● Web上でGoを実行できる
● Share機能で、SNSで共有したり質問する
ハンズオン/Go Playground
131

More Related Content

What's hot

GoによるWebアプリ開発のキホン
GoによるWebアプリ開発のキホンGoによるWebアプリ開発のキホン
GoによるWebアプリ開発のキホンAkihiko Horiuchi
 
Dockerfile を書くためのベストプラクティス解説編
Dockerfile を書くためのベストプラクティス解説編Dockerfile を書くためのベストプラクティス解説編
Dockerfile を書くためのベストプラクティス解説編Masahito Zembutsu
 
Go mobileでモバイルアプリを作ろう
Go mobileでモバイルアプリを作ろうGo mobileでモバイルアプリを作ろう
Go mobileでモバイルアプリを作ろうTakuya Ueda
 
Dockerfileを改善するためのBest Practice 2019年版
Dockerfileを改善するためのBest Practice 2019年版Dockerfileを改善するためのBest Practice 2019年版
Dockerfileを改善するためのBest Practice 2019年版Masahito Zembutsu
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチンyohhoy
 
ドメイン駆動設計 基本を理解する
ドメイン駆動設計 基本を理解するドメイン駆動設計 基本を理解する
ドメイン駆動設計 基本を理解する増田 亨
 
Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方Taku Miyakawa
 
JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)
JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)
JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)Yoshiro Tokumasu
 
Redmineをちょっと便利に! プログラミング無しで使ってみるREST API
Redmineをちょっと便利に! プログラミング無しで使ってみるREST APIRedmineをちょっと便利に! プログラミング無しで使ってみるREST API
Redmineをちょっと便利に! プログラミング無しで使ってみるREST APIGo Maeda
 
Goでwebアプリを開発してみよう
Goでwebアプリを開発してみようGoでwebアプリを開発してみよう
Goでwebアプリを開発してみようTakuya Ueda
 
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのかDDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのかKoichiro Matsuoka
 
ドメインオブジェクトの見つけ方・作り方・育て方
ドメインオブジェクトの見つけ方・作り方・育て方ドメインオブジェクトの見つけ方・作り方・育て方
ドメインオブジェクトの見つけ方・作り方・育て方増田 亨
 
目grep入門 +解説
目grep入門 +解説目grep入門 +解説
目grep入門 +解説murachue
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Kohei Tokunaga
 
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーWhere狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーyoku0825
 
雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニング雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニングyoku0825
 
PHP-FPM の子プロセス制御方法と設定をおさらいしよう
PHP-FPM の子プロセス制御方法と設定をおさらいしようPHP-FPM の子プロセス制御方法と設定をおさらいしよう
PHP-FPM の子プロセス制御方法と設定をおさらいしようShohei Okada
 
Twitterのsnowflakeについて
TwitterのsnowflakeについてTwitterのsnowflakeについて
Twitterのsnowflakeについてmoai kids
 

What's hot (20)

GoによるWebアプリ開発のキホン
GoによるWebアプリ開発のキホンGoによるWebアプリ開発のキホン
GoによるWebアプリ開発のキホン
 
Dockerfile を書くためのベストプラクティス解説編
Dockerfile を書くためのベストプラクティス解説編Dockerfile を書くためのベストプラクティス解説編
Dockerfile を書くためのベストプラクティス解説編
 
gRPC入門
gRPC入門gRPC入門
gRPC入門
 
Go mobileでモバイルアプリを作ろう
Go mobileでモバイルアプリを作ろうGo mobileでモバイルアプリを作ろう
Go mobileでモバイルアプリを作ろう
 
Dockerfileを改善するためのBest Practice 2019年版
Dockerfileを改善するためのBest Practice 2019年版Dockerfileを改善するためのBest Practice 2019年版
Dockerfileを改善するためのBest Practice 2019年版
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
 
ドメイン駆動設計 基本を理解する
ドメイン駆動設計 基本を理解するドメイン駆動設計 基本を理解する
ドメイン駆動設計 基本を理解する
 
Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方
 
JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)
JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)
JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)
 
Redmineをちょっと便利に! プログラミング無しで使ってみるREST API
Redmineをちょっと便利に! プログラミング無しで使ってみるREST APIRedmineをちょっと便利に! プログラミング無しで使ってみるREST API
Redmineをちょっと便利に! プログラミング無しで使ってみるREST API
 
Goでwebアプリを開発してみよう
Goでwebアプリを開発してみようGoでwebアプリを開発してみよう
Goでwebアプリを開発してみよう
 
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのかDDDのモデリングとは何なのか、 そしてどうコードに落とすのか
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
 
ドメインオブジェクトの見つけ方・作り方・育て方
ドメインオブジェクトの見つけ方・作り方・育て方ドメインオブジェクトの見つけ方・作り方・育て方
ドメインオブジェクトの見つけ方・作り方・育て方
 
目grep入門 +解説
目grep入門 +解説目grep入門 +解説
目grep入門 +解説
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
 
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーWhere狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキー
 
雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニング雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニング
 
PHP-FPM の子プロセス制御方法と設定をおさらいしよう
PHP-FPM の子プロセス制御方法と設定をおさらいしようPHP-FPM の子プロセス制御方法と設定をおさらいしよう
PHP-FPM の子プロセス制御方法と設定をおさらいしよう
 
Twitterのsnowflakeについて
TwitterのsnowflakeについてTwitterのsnowflakeについて
Twitterのsnowflakeについて
 
GoでMinecraftっぽいの作る
GoでMinecraftっぽいの作るGoでMinecraftっぽいの作る
GoでMinecraftっぽいの作る
 

Viewers also liked

Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会
Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会
Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会Takuya Ueda
 
GopherFest 2017 - Adding Context to NATS
GopherFest 2017 -  Adding Context to NATSGopherFest 2017 -  Adding Context to NATS
GopherFest 2017 - Adding Context to NATSwallyqs
 
Real world android akka
Real world android akkaReal world android akka
Real world android akkaTaisuke Oe
 
What Dotty fixes @ Scala関西サミット
What Dotty fixes @ Scala関西サミットWhat Dotty fixes @ Scala関西サミット
What Dotty fixes @ Scala関西サミットTaisuke Oe
 
FINAL FANTASY Record Keeperを支えたGolang
FINAL FANTASY Record Keeperを支えたGolangFINAL FANTASY Record Keeperを支えたGolang
FINAL FANTASY Record Keeperを支えたGolangYoshiki Shibukawa
 
Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術Naoki Aoyama
 
iOSエンジニアのためのScala入門
iOSエンジニアのためのScala入門iOSエンジニアのためのScala入門
iOSエンジニアのためのScala入門Masaya Dake
 
【初心者向け】Go言語勉強会資料
 【初心者向け】Go言語勉強会資料 【初心者向け】Go言語勉強会資料
【初心者向け】Go言語勉強会資料Yuji Otani
 
Mobile Apps by Pure Go with Reverse Binding
Mobile Apps by Pure Go with Reverse BindingMobile Apps by Pure Go with Reverse Binding
Mobile Apps by Pure Go with Reverse BindingTakuya Ueda
 
Go1.8 for Google App Engine
Go1.8 for Google App EngineGo1.8 for Google App Engine
Go1.8 for Google App EngineTakuya Ueda
 
粗探しをしてGoのコントリビューターになる方法
粗探しをしてGoのコントリビューターになる方法粗探しをしてGoのコントリビューターになる方法
粗探しをしてGoのコントリビューターになる方法Takuya Ueda
 
HTTP2 RFC 発行記念祝賀会
HTTP2 RFC 発行記念祝賀会HTTP2 RFC 発行記念祝賀会
HTTP2 RFC 発行記念祝賀会Jxck Jxck
 
Static Analysis in Go
Static Analysis in GoStatic Analysis in Go
Static Analysis in GoTakuya Ueda
 
Cloud Functionsの紹介
Cloud Functionsの紹介Cloud Functionsの紹介
Cloud Functionsの紹介Takuya Ueda
 
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話Takuya Ueda
 
GoによるiOSアプリの開発
GoによるiOSアプリの開発GoによるiOSアプリの開発
GoによるiOSアプリの開発Takuya Ueda
 
Namespace API を用いたマルチテナント型 Web アプリの実践
Namespace API を用いたマルチテナント型 Web アプリの実践Namespace API を用いたマルチテナント型 Web アプリの実践
Namespace API を用いたマルチテナント型 Web アプリの実践Takuya Ueda
 
goパッケージで型情報を用いたソースコード検索を実現する
goパッケージで型情報を用いたソースコード検索を実現するgoパッケージで型情報を用いたソースコード検索を実現する
goパッケージで型情報を用いたソースコード検索を実現するTakuya Ueda
 
Go静的解析ハンズオン
Go静的解析ハンズオンGo静的解析ハンズオン
Go静的解析ハンズオンTakuya Ueda
 

Viewers also liked (20)

Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会
Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会
Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会
 
GopherFest 2017 - Adding Context to NATS
GopherFest 2017 -  Adding Context to NATSGopherFest 2017 -  Adding Context to NATS
GopherFest 2017 - Adding Context to NATS
 
Real world android akka
Real world android akkaReal world android akka
Real world android akka
 
What Dotty fixes @ Scala関西サミット
What Dotty fixes @ Scala関西サミットWhat Dotty fixes @ Scala関西サミット
What Dotty fixes @ Scala関西サミット
 
Golang
GolangGolang
Golang
 
FINAL FANTASY Record Keeperを支えたGolang
FINAL FANTASY Record Keeperを支えたGolangFINAL FANTASY Record Keeperを支えたGolang
FINAL FANTASY Record Keeperを支えたGolang
 
Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術
 
iOSエンジニアのためのScala入門
iOSエンジニアのためのScala入門iOSエンジニアのためのScala入門
iOSエンジニアのためのScala入門
 
【初心者向け】Go言語勉強会資料
 【初心者向け】Go言語勉強会資料 【初心者向け】Go言語勉強会資料
【初心者向け】Go言語勉強会資料
 
Mobile Apps by Pure Go with Reverse Binding
Mobile Apps by Pure Go with Reverse BindingMobile Apps by Pure Go with Reverse Binding
Mobile Apps by Pure Go with Reverse Binding
 
Go1.8 for Google App Engine
Go1.8 for Google App EngineGo1.8 for Google App Engine
Go1.8 for Google App Engine
 
粗探しをしてGoのコントリビューターになる方法
粗探しをしてGoのコントリビューターになる方法粗探しをしてGoのコントリビューターになる方法
粗探しをしてGoのコントリビューターになる方法
 
HTTP2 RFC 発行記念祝賀会
HTTP2 RFC 発行記念祝賀会HTTP2 RFC 発行記念祝賀会
HTTP2 RFC 発行記念祝賀会
 
Static Analysis in Go
Static Analysis in GoStatic Analysis in Go
Static Analysis in Go
 
Cloud Functionsの紹介
Cloud Functionsの紹介Cloud Functionsの紹介
Cloud Functionsの紹介
 
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話
 
GoによるiOSアプリの開発
GoによるiOSアプリの開発GoによるiOSアプリの開発
GoによるiOSアプリの開発
 
Namespace API を用いたマルチテナント型 Web アプリの実践
Namespace API を用いたマルチテナント型 Web アプリの実践Namespace API を用いたマルチテナント型 Web アプリの実践
Namespace API を用いたマルチテナント型 Web アプリの実践
 
goパッケージで型情報を用いたソースコード検索を実現する
goパッケージで型情報を用いたソースコード検索を実現するgoパッケージで型情報を用いたソースコード検索を実現する
goパッケージで型情報を用いたソースコード検索を実現する
 
Go静的解析ハンズオン
Go静的解析ハンズオンGo静的解析ハンズオン
Go静的解析ハンズオン
 

Similar to Go入門

Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析Takuya Ueda
 
エキスパートGo
エキスパートGoエキスパートGo
エキスパートGoTakuya Ueda
 
エディタの壁を越えるGoの開発ツールの文化と作成法
エディタの壁を越えるGoの開発ツールの文化と作成法エディタの壁を越えるGoの開発ツールの文化と作成法
エディタの壁を越えるGoの開発ツールの文化と作成法Takuya Ueda
 
Goにおける静的解析と製品開発への応用
Goにおける静的解析と製品開発への応用Goにおける静的解析と製品開発への応用
Goにおける静的解析と製品開発への応用Takuya Ueda
 
実践Go ツールの作成から配布まで
実践Go ツールの作成から配布まで実践Go ツールの作成から配布まで
実践Go ツールの作成から配布までYusuke Miyake
 
Go言語ってどんな言語? 導入実績や気になるトレンド
Go言語ってどんな言語? 導入実績や気になるトレンドGo言語ってどんな言語? 導入実績や気になるトレンド
Go言語ってどんな言語? 導入実績や気になるトレンドAtsushi Yasuda
 
メルカリ・ソウゾウでは どうGoを活用しているのか?
メルカリ・ソウゾウでは どうGoを活用しているのか?メルカリ・ソウゾウでは どうGoを活用しているのか?
メルカリ・ソウゾウでは どうGoを活用しているのか?Takuya Ueda
 
Code Reading at Security and Programming camp 2011
Code Reading at Security and Programming camp 2011 Code Reading at Security and Programming camp 2011
Code Reading at Security and Programming camp 2011 Hiro Yoshioka
 
今日から始める Go言語 と appengine
今日から始める Go言語 と appengine今日から始める Go言語 と appengine
今日から始める Go言語 と appenginea know
 
Programming camp Codereading
Programming camp CodereadingProgramming camp Codereading
Programming camp CodereadingHiro Yoshioka
 
勉強会 Cvml python基礎
勉強会 Cvml python基礎勉強会 Cvml python基礎
勉強会 Cvml python基礎真哉 杉野
 
今最もアツイdistribution Gentoo Linuxについて
今最もアツイdistribution Gentoo Linuxについて今最もアツイdistribution Gentoo Linuxについて
今最もアツイdistribution Gentoo LinuxについてTakuto Matsuu
 
マスター・オブ・reflectパッケージ II
マスター・オブ・reflectパッケージ IIマスター・オブ・reflectパッケージ II
マスター・オブ・reflectパッケージ IITakuya Ueda
 
Programming camp 2008, Codereading
Programming camp 2008, CodereadingProgramming camp 2008, Codereading
Programming camp 2008, CodereadingHiro Yoshioka
 
Microsoft Graph API Library for Go
Microsoft Graph API Library for GoMicrosoft Graph API Library for Go
Microsoft Graph API Library for Goyaegashi
 
GAE/GoでWebアプリ開発入門
GAE/GoでWebアプリ開発入門GAE/GoでWebアプリ開発入門
GAE/GoでWebアプリ開発入門Takuya Ueda
 
Programming camp code reading
Programming camp code readingProgramming camp code reading
Programming camp code readingHiro Yoshioka
 
AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?
AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?
AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?Masamitsu Maehara
 
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyotoGo言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyotoShoot Morii
 

Similar to Go入門 (20)

Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析
 
エキスパートGo
エキスパートGoエキスパートGo
エキスパートGo
 
エディタの壁を越えるGoの開発ツールの文化と作成法
エディタの壁を越えるGoの開発ツールの文化と作成法エディタの壁を越えるGoの開発ツールの文化と作成法
エディタの壁を越えるGoの開発ツールの文化と作成法
 
Goにおける静的解析と製品開発への応用
Goにおける静的解析と製品開発への応用Goにおける静的解析と製品開発への応用
Goにおける静的解析と製品開発への応用
 
実践Go ツールの作成から配布まで
実践Go ツールの作成から配布まで実践Go ツールの作成から配布まで
実践Go ツールの作成から配布まで
 
Go言語ってどんな言語? 導入実績や気になるトレンド
Go言語ってどんな言語? 導入実績や気になるトレンドGo言語ってどんな言語? 導入実績や気になるトレンド
Go言語ってどんな言語? 導入実績や気になるトレンド
 
メルカリ・ソウゾウでは どうGoを活用しているのか?
メルカリ・ソウゾウでは どうGoを活用しているのか?メルカリ・ソウゾウでは どうGoを活用しているのか?
メルカリ・ソウゾウでは どうGoを活用しているのか?
 
Code Reading at Security and Programming camp 2011
Code Reading at Security and Programming camp 2011 Code Reading at Security and Programming camp 2011
Code Reading at Security and Programming camp 2011
 
今日から始める Go言語 と appengine
今日から始める Go言語 と appengine今日から始める Go言語 と appengine
今日から始める Go言語 と appengine
 
Programming camp Codereading
Programming camp CodereadingProgramming camp Codereading
Programming camp Codereading
 
勉強会 Cvml python基礎
勉強会 Cvml python基礎勉強会 Cvml python基礎
勉強会 Cvml python基礎
 
今最もアツイdistribution Gentoo Linuxについて
今最もアツイdistribution Gentoo Linuxについて今最もアツイdistribution Gentoo Linuxについて
今最もアツイdistribution Gentoo Linuxについて
 
マスター・オブ・reflectパッケージ II
マスター・オブ・reflectパッケージ IIマスター・オブ・reflectパッケージ II
マスター・オブ・reflectパッケージ II
 
Programming camp 2008, Codereading
Programming camp 2008, CodereadingProgramming camp 2008, Codereading
Programming camp 2008, Codereading
 
Microsoft Graph API Library for Go
Microsoft Graph API Library for GoMicrosoft Graph API Library for Go
Microsoft Graph API Library for Go
 
GAE/GoでWebアプリ開発入門
GAE/GoでWebアプリ開発入門GAE/GoでWebアプリ開発入門
GAE/GoでWebアプリ開発入門
 
Programming camp code reading
Programming camp code readingProgramming camp code reading
Programming camp code reading
 
AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?
AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?
AWS Security JAWS 経済的にハニーポットのログ分析をするためのベストプラクティス?
 
Goとテスト
GoとテストGoとテスト
Goとテスト
 
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyotoGo言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
 

More from Takuya Ueda

Goにおけるバージョン管理の必要性 − vgoについて −
Goにおけるバージョン管理の必要性 − vgoについて −Goにおけるバージョン管理の必要性 − vgoについて −
Goにおけるバージョン管理の必要性 − vgoについて −Takuya Ueda
 
WebAssembly with Go
WebAssembly with GoWebAssembly with Go
WebAssembly with GoTakuya Ueda
 
GAE/Goとsyncパッケージ
GAE/GoとsyncパッケージGAE/Goとsyncパッケージ
GAE/GoとsyncパッケージTakuya Ueda
 
静的解析を使った開発ツールの開発
静的解析を使った開発ツールの開発静的解析を使った開発ツールの開発
静的解析を使った開発ツールの開発Takuya Ueda
 
そうだ、Goを始めよう
そうだ、Goを始めようそうだ、Goを始めよう
そうだ、Goを始めようTakuya Ueda
 
マスター・オブ・goパッケージ
マスター・オブ・goパッケージマスター・オブ・goパッケージ
マスター・オブ・goパッケージTakuya Ueda
 
メルカリ カウルのマスタデータの更新
メルカリ カウルのマスタデータの更新メルカリ カウルのマスタデータの更新
メルカリ カウルのマスタデータの更新Takuya Ueda
 
Go Friday 傑作選
Go Friday 傑作選Go Friday 傑作選
Go Friday 傑作選Takuya Ueda
 
オススメの標準・準標準パッケージ20選
オススメの標準・準標準パッケージ20選オススメの標準・準標準パッケージ20選
オススメの標準・準標準パッケージ20選Takuya Ueda
 
Gopher Fest 2017参加レポート
Gopher Fest 2017参加レポートGopher Fest 2017参加レポート
Gopher Fest 2017参加レポートTakuya Ueda
 
Google Assistant関係のセッションまとめ
Google Assistant関係のセッションまとめGoogle Assistant関係のセッションまとめ
Google Assistant関係のセッションまとめTakuya Ueda
 
Cloud functionsの紹介
Cloud functionsの紹介Cloud functionsの紹介
Cloud functionsの紹介Takuya Ueda
 
条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化Takuya Ueda
 
GAE/GoでLINE Messaging API を使う
GAE/GoでLINE Messaging API を使うGAE/GoでLINE Messaging API を使う
GAE/GoでLINE Messaging API を使うTakuya Ueda
 

More from Takuya Ueda (14)

Goにおけるバージョン管理の必要性 − vgoについて −
Goにおけるバージョン管理の必要性 − vgoについて −Goにおけるバージョン管理の必要性 − vgoについて −
Goにおけるバージョン管理の必要性 − vgoについて −
 
WebAssembly with Go
WebAssembly with GoWebAssembly with Go
WebAssembly with Go
 
GAE/Goとsyncパッケージ
GAE/GoとsyncパッケージGAE/Goとsyncパッケージ
GAE/Goとsyncパッケージ
 
静的解析を使った開発ツールの開発
静的解析を使った開発ツールの開発静的解析を使った開発ツールの開発
静的解析を使った開発ツールの開発
 
そうだ、Goを始めよう
そうだ、Goを始めようそうだ、Goを始めよう
そうだ、Goを始めよう
 
マスター・オブ・goパッケージ
マスター・オブ・goパッケージマスター・オブ・goパッケージ
マスター・オブ・goパッケージ
 
メルカリ カウルのマスタデータの更新
メルカリ カウルのマスタデータの更新メルカリ カウルのマスタデータの更新
メルカリ カウルのマスタデータの更新
 
Go Friday 傑作選
Go Friday 傑作選Go Friday 傑作選
Go Friday 傑作選
 
オススメの標準・準標準パッケージ20選
オススメの標準・準標準パッケージ20選オススメの標準・準標準パッケージ20選
オススメの標準・準標準パッケージ20選
 
Gopher Fest 2017参加レポート
Gopher Fest 2017参加レポートGopher Fest 2017参加レポート
Gopher Fest 2017参加レポート
 
Google Assistant関係のセッションまとめ
Google Assistant関係のセッションまとめGoogle Assistant関係のセッションまとめ
Google Assistant関係のセッションまとめ
 
Cloud functionsの紹介
Cloud functionsの紹介Cloud functionsの紹介
Cloud functionsの紹介
 
条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化
 
GAE/GoでLINE Messaging API を使う
GAE/GoでLINE Messaging API を使うGAE/GoでLINE Messaging API を使う
GAE/GoでLINE Messaging API を使う
 

Recently uploaded

PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000Shota Ito
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxAtomu Hidaka
 
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 
プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価sugiuralab
 
プレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツールプレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツールsugiuralab
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directoryosamut
 
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 

Recently uploaded (7)

PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
 
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
 
プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価プレイマットのパターン生成支援ツールの評価
プレイマットのパターン生成支援ツールの評価
 
プレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツールプレイマットのパターン生成支援ツール
プレイマットのパターン生成支援ツール
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory
 
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
 

Go入門