SlideShare a Scribd company logo
The Go gopher was designed by Renée French.
The gopher stickers was made by Takuya Ueda.
Licensed under the Creative Commons 3.0 Attributions license.
マスター・オブ・goパッケージ
@会津大Go言語+仮想通貨勉強会
2017年12月10日
1
※ この資料はGolangUK 2017の発表資料を改良したものです
自己紹介
上田拓也
@tenntenn
所属
コミュニティ活動
&
Go ビギナーズ
Go Conference
上田拓也
@tenntenn
2
ソウゾウ エキスパートチーム
技術をアウトプットするところに技術は集まる
■ エキスパートチームとは?
● 50%以上の時間を技術コミュニティへの貢献に充てる
■ エキスパートチームの役割
● 社内に新しい技術を取り取り込む
● 社外のコミュニティなどを通じて社会へ還元する
■ エキスパートチームの活動
● カンファレンス・勉強会の開催/運営
● 対外的な講演活動
● 執筆、雑誌への寄稿、インタビュー
● 社内外での担当技術の普及推進
@tenntenn
担当:Go・GCP
@mhidaka
担当:Android
メンバー
3
アジェンダ
■ Gopherを探せ!
■ 静的解析
■ Goにおける静的解析
■ 静的解析の製品開発への応用
4
Gopherを探せ!
みつけてね
Powered by https://gopherize.me
5
Gopherを探せ!
みつけてね
Powered by https://gopherize.me
6
"Gopher"を探せ!
type Gopher struct { Gopher string `json:"gopher"` }
func main() {
const gopher = "GOPHER"
gogopher := GOPHER()
gogopher.Gopher = gopher
fmt.Println(gogopher)
}
func GOPHER() (gopher *Gopher) {
gopher = &Gopher{ Gopher: "gopher" }
return
}
7
みんな大好きgrep
$ grep Gopher main.go
type Gopher struct { Gopher string `json:"gopher"` }
gogopher.Gopher = gopher
func GOPHER() (gopher *Gopher) {
gopher = &Gopher{ Gopher: "gopher" }
grepで"Gopher"を探す
8
"Gopher" 型を探せ!
type Gopher struct { Gopher string `json:"gopher"` }
func main() {
const gopher = "GOPHER"
gogopher := GOPHER()
gogopher.Gopher = gopher
fmt.Println(gogopher)
}
func GOPHER() (gopher *Gopher) {
gopher = &Gopher{ Gopher: "gopher" }
return
}
9
"Gopher"型を探すには?
■ grep だと文字列としてしか検索できない
■ 文字列ではなくGoのソースコードとして
理解しないといけない
■ そこで静的解析を使う!
10
静的解析
11
静的解析と動的解析
■ 静的解析
● プログラムを実行せずに解析すること
● ソースコードを解析する
● 例:lint、コード補完、 コードフォーマッタ
■ 動的解析
● プログラムを実行して解析すること
● 実行時 変数 状態や関数 実行順などを検証
● 例:レースコンディション
12
リフレクション
■ リフレクション
● 実行時に型や値 情報を解析する
■ Goにおけるリフレクション
● reflectパッケージを使う
● 実行時にstructタグにアクセスする唯一の方法
● 出力引数としてポインタを貰ってきた場合に値を入れるために使用
● JSONやXMLなどのエンコードに使用
13
Goの静的解析ツール
■ Goには多くの静的解析ツールが存在する
gofmt/goimports コードフォーマッタ
go vet/golint コードチェッカー、リンター
guru 静的解析
gocode コード補完
errcheck エラー処理のチェック
gorename/gomvpkg リファクタリング
14
Goと静的解析
■ 静的解析しやすいように設計されている
● 静的型付け
● 文法がシンプル
● 型推論
● 暗黙の型変換がない
● 標準パッケージで静的解析の機能を提供
静的解析では多くの情報を取得できる
15
go パッケージ
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 型チェックに関する機能を提供
16
Goにおける静的解析
17
静的解析の流れ
ソースコード
トークン
抽象構文木
(AST)
型情報
構文解析
字句解析
型チェック
go/scanner
go/token
go/parser
go/ast
go/types
go/constant
18
■ 入力された文字列をトークンとして分解
字句解析- go/scanner,go/token
IDENT ADD INT
トークン
ソースコード: v + 1
19
構文解析 - go/parser,go/ast
■ トークンを抽象構文木(AST)に変換
v + 1
IDENT ADD INT
ソースコード:
+
v 1
BinaryExpr
Ident BasicLit
トークン:
抽象構文(AST):
20
"Hello, World"の抽象構文木
package main
import "fmt"
func main() {
fmt.Println("Hello, 世界")
}
Run on Playground
*ast.File
[]ast.Decl
*ast.GenDecl *ast.FuncDecl
21
型チェック - go/types,go/constant
■ 型情報を抽象構文木から抽出
● 識別子の解決
● 型の推論
● 定数の評価
n := 100 + 200
m := n + 300
定数の評価
= 300
型の推論
-> int
識別子の解決
22
ソースコードから抽象構文木の取得
■ parser.Parse* 系の関数を使う
● ParseExpr,ParseExprFrom
○ 式をパースする
○ ParseExpr は ParseExprFrom のシンプルバージョン
● ParseFile
○ ファイルをパースする
● ParseDir
○ ディレクトリ単位でパースする
○ 内部で ParseFile を呼んでいる
23
式の抽象構文木を取得する
expr, err := parser.ParseExpr(`v + 1`)
if err != nil {
/* handling the error */
}
/* use expr */
■ 式単位でパースする
24
ファイル単位で抽象構文木を取得
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 {
/* handling the error */
}
/* use f */
srcがnilの場合だと
ファイル名を元にファイルが開かれる
ソースコード
パースモード
25
token.FileSet
■ ファイル中の位置情報を記録する為の型
● token.Posは数値として記録
● 複数ファイル間で共通の値が使われる
● token.FileSet は各ファイルのオフセットを記録
● オフセットはパース時に記録される
● token.FileSet はparser.Parse*系の関数に出力引数として渡される
type Pos int
26
デモ 1: 構文解析と抽象構文木の出力
27
https://youtu.be/lM1Pj6xYxZs
Demo Code: https://gist.github.com/tenntenn/833207ce1715089da23936b5dfaebea5
抽象構文木の探索- ast.Inspect
■ Using ast.Inspect
expr, _ := parser.ParseExpr(`v + 1`)
ast.Inspect(expr, func(n ast.Node) bool {
if n != nil { fmt.Printf("%Tn", n) }
return true
})
抽象構文木の探索
*ast.BinaryExpr
*ast.Ident
*ast.BasicLit
Playgroundで実行
ast.Walk はもっと複雑な処理ができる
+
v 1
BinaryExpr
Ident BasicLit
28
抽象構文木の探索 - 再帰
func traverse(n ast.Node) {
switch n := n.(type) {
case *ast.Ident:
fmt.Println(n.Name)
case *ast.BinaryExpr:
traverse(n.X)
traverse(n.Y)
case *ast.UnaryExpr:
traverse(n.X)
default:
fmt.Println(n)
}
}
識別子:識別子名を出力
2項演算式:各項について再帰的に探索
型で処理を分岐
Playgroundで実行
単項演算式:項を再帰的に探索
29
デモ 2: 識別子の探索
30
https://youtu.be/mpUgaaASvHo
Demo Code: https://gist.github.com/tenntenn/299c226c540fccd8386b7148f55f0884
型チェック
/* 型チェックのためのConfigを初期化 */
cfg := &types.Config{Importer: importer.Default()}
info := &types.Info{
/* TODO: 結果を保持するためのmapを初期化 */
}
pkg, err := cfg.Check("main", fs, []*ast.File{f}, info)
if err != nil {
/* エラー処理 */
}
/* TODO: pkgやinfoを使う処理 */
■ (*types.Config).Check で型チェックを行う
31
types.Info で型チェックの結果を保持する
type Info struct {
// Types maps expressions to their types, and for constant
// expressions, also their values.
Types map[ast.Expr]TypeAndValue
// Defs maps identifiers to the objects they define.
Defs map[*ast.Ident]Object
// Uses maps identifiers to the objects they denote.
Uses map[*ast.Ident]Object
// Implicits maps nodes to their implicitly declared objects, if any.
Implicits map[ast.Node]Object
// Selections maps selector expressions (excluding qualified identifiers)
// to their corresponding selections.
Selections map[*ast.SelectorExpr]*Selection
// Scopes maps ast.Nodes to the scopes they define.
Scopes map[ast.Node]*Scope
// InitOrder is the list of package-level initializers in the order in which
// they must be executed.
InitOrder []*Initializer
}
32
デモ 3: Gopher型の探索
33
https://youtu.be/AuSDtmiMaXI
Demo Code: https://gist.github.com/tenntenn/134d6965f75efe5eb6f6edf7b0ebe509
抽象構文木の変更
34
■ 抽象構文木を探索&条件マッチするノードの置き換え
● 2項演算式中の第2項だけを変更する
● 1ノードだけみるast.Inspectやast.Walkでは難しい!
○ go/ast: provide AST Rewrite functionality (ast.Walk is not good enough)
+
X Y
BinaryExpr
Ident
+
X 2
BasicLit
astutil.Apply関数
■ 抽象構文木を変更するための関数
● golang.org/x/tools/go/ast/astutilパッケージで提供
● preとpostというノードに適用する関数を渡す
○ pre: 子ノードを処理する前に呼ばれる関数
○ post: 子ノードを処理した後に呼ばれる関数
● 変更した結果をresultとして返す
○ ルートが変更された場合はrootとresultが変わる
35
参考:astutil.Applyで抽象構文木を置き換える
func Apply(root ast.Node, pre, post ApplyFunc) (result ast.Node)
ApplyFunc型とCursor型
■ ApplyFunc型
● astutil.Apply関数に各ノードに再帰的に適用される関数
■ Cursor型
● 現在注目しているノードに関する情報を保持する型
● ノードの情報を取得するメソッド
○ Node、Index、Parent、Name
● ノードの操作を行うメソッド
○ Replace、Delete、InsertBefore、InsertAfter
36
type ApplyFunc func(*Cursor) bool
ノードの情報を取得するメソッド
■ Node() ast.Node
● 現在注目のノード取得する
■ Parent() ast.Node
● 注目ノードの親ノードを取得
■ Name() string
● 親ノードにどういう名前でノードを管理されているか
○ 例:BinaryExprの場合、2つの項はXとY
■ Index() int
● 親ノードでスライスとして管理していた場合にそのインデックス
○ 例:関数の引数など
● Nameメソッドだけで区別できない場合に使う
37
ノードを変更するメソッド
■ Replace(n ast.Node)
● 現在注目のノードを指定したノードで入れ替える
■ InsertBefore(n ast.Node)
● スライスで管理されているノードが対象
● 現在注目のノードの前にノードを追加する
■ InsertAfter(n ast.Node)
● 現在注目のノードの後ろにノードを追加する
■ Delete()
● 現在注目のノードを削除する
38
ノードの更新の例
39
expr, err := parser.ParseExpr(`x+y`)
if err != nil { log.Fatal(err) }
n := astutil.Apply(expr, func(cr *astutil.Cursor) bool {
if _, ok := cr.Parent().(*ast.BinaryExpr); !ok { return true }
if cr.Name() == "Y" {
cr.Replace(&ast.BasicLit{Kind:token.INT, Value:"2"})
}
return true
}, nil)
if err := format.Node(os.Stdout, token.NewFileSet(), n); err != nil {
log.Fatalln("Error:", err)
}
fmt.Println()
ノードを操作する際の注意点
■ ノードの操作は破壊的に行われる
● コピーが作られるわけではない
● Apply関数の戻り値はちゃんと受け取る
■ ノードの操作は即時反映される
● preとpostは実行された瞬間にそのノードに適用される
40
ノードの削除の例(失敗例)
41
■ 第1引数だけを削除したい
expr, err := parser.ParseExpr(`func(x, y int){}(10, 20)`)
if err != nil { log.Fatal(err) }
n := astutil.Apply(expr, func(cr *astutil.Cursor) bool {
if cr.Name() == "Args" && cr.Index() == 0 {
cr.Delete()
}
return true
}, nil)
if err := format.Node(os.Stdout, token.NewFileSet(), n); err != nil {
log.Fatalln("Error:", err)
}
fmt.Println()
ノードの削除の例(修正版)
42
■ 第1引数を一度だけ削除する
expr, err := parser.ParseExpr(`func(x, y int){}(10, 20)`)
if err != nil { log.Fatal(err) }
var once sync.Once
n := astutil.Apply(expr, func(cr *astutil.Cursor) bool {
if cr.Name() == "Args" && cr.Index() == 0 {
once.Do(cr.Delete)
}
return true
}, nil)
if err := format.Node(os.Stdout, token.NewFileSet(), n); err != nil {
log.Fatalln("Error:", err)
}
fmt.Println()
静的解析の製品開発への応用
ケース 1: gpath,go-httpdoc
43
go.mercari.io/go-httpdoc
■ HTTPハンドラのテストからAPIドキュメントを生成
● 単にHTTPハンドラのテストを書くだけで良い
● gRPCとJSON RPCにも対応している
44
主にdeeeetさん作
リクエストとレスポンスのテスト
■ リクエストのテストからドキュメントを生成
● Request Bodyをリフレクションでテストしている
● 構造体の任意のフィールドを指定できる
validator.RequestBody(t, []httpdoc.TestCase{
{"Name", "tenntenn", "User Name"},
{"Attribute.Email", "tenntenn@example.com", "e-mail address"},
}, &createUserRequest{})
45
参考:go-httpdocのexample
github.com/tenntenn/gpath
■ 構造体の任意のフィールドにアクセスできる
● 複雑なリフレクションが簡単に書ける
● Goの式で記述できる
● スライスやマップにも対応している
type Bar struct { N []int }
type Foo struct { Bar *Bar }
f := &Foo{ Bar: &Bar{ N: []int{100} }}
v, _ := At(f, `Bar.N[0]`)
fmt.Println(v)
$ go run main.go
100
46
開発ツールへ静的解析を使う
■ 自作開発ツールでレビューコストを下げる
● 自動化できることは自動化する(カラクリ)
○ 自分のプロジェクト用にカスタマイズされたリンターを作る
○ よくあるバグを検出するツールを作る
● レビューの時間はもっと重要なことに使う
○ アルゴリズムの検証
○ 設計
○ パフォーマンス
47
静的解析の製品開発への応用
ケース 2: バナーツール
48
デモ:https://goo.gl/HzHTm6
バナーツール
■ アプリ内バナーを管理するツール
アプリ内バナー
メルカリ アッテのタイムライン
49
主にtenntenn作
バナーツール
■ アプリ内バナーを管理するツール
バナーツール
● 配信条件式
● レスポンス
バナーの取得
OS, API バージョン
配信可能バナーのリストを返却
画像URL, 遷移先URLなど
Apps
50
配信条件式の評価
バナーの取得
GET /banner/?os=1
String(os) == "1"
バナー画像URLなど
配信条件式:
バナーツール
"1" == "1"
true
束縛
評価
■ 配信条件をGoの式に似た形式で記述する
● go パッケージを使って式を評価する
● 型つき変数として関数呼び出しの記述方式を利用
51
静的解析の製品開発への応用
ケース 3: Datastore Wrapper
52
参考:ぼくが かんがえた さいきょうの でーたすとあ らっぱー
go.mercari.io/datastore
53
■ Datastoreとは
● 主にGoogle App Engine(GAE)で使われるキーバリューストア
■ Datastore Wrapper
● Datastoreのライブラリの使いにくいところを改善
● GAEガチ勢のノウハウを凝縮したライブラリ
● DatastoreのRPCのコールの回数を減らすバッチ処理など
vvakameさん作
移行ツールの作成
■ 既存のプロジェクトでDatastore Wrapperを使う
● 既存のコードの置き換えが大変
● import文の変更などは自動化できる
● カスタマイズされたものを作る方が利便性が高い
■ astutil.Apply関数の利用
● 複雑な置き換えが可能
● 条件式にマッチしたものを置き換えれる
54
まとめ
■ Goで静的解析を行うのは簡単
● 静的型付け、シンプルな文法、goパッケージ
■ goパッケージで簡単に静的解析を行える
● 字句解析、構文解析、型チェック
■ 製品開発での静的解析の利用
● 自作の静的解析ツール (例:gpath, go-httpdoc)
● Webアプリ(例: Banner Tool)
● マイグレーションツール(例:Datastore Wrapper)
55
Thank you!
twitter: @tenntenn
Qiita: tenntenn
connpass: tenntenn
56

More Related Content

What's hot

Goとテスト
GoとテストGoとテスト
Goとテスト
Takuya Ueda
 
マスター・オブ・Reflectパッケージ
マスター・オブ・Reflectパッケージマスター・オブ・Reflectパッケージ
マスター・オブ・Reflectパッケージ
Takuya Ueda
 
GAE/GoでWebアプリ開発入門
GAE/GoでWebアプリ開発入門GAE/GoでWebアプリ開発入門
GAE/GoでWebアプリ開発入門
Takuya Ueda
 
インタフェースの実装パターン
インタフェースの実装パターンインタフェースの実装パターン
インタフェースの実装パターンTakuya Ueda
 
条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化
Takuya Ueda
 
Goで言語処理系(の途中まで)を作ろう
Goで言語処理系(の途中まで)を作ろうGoで言語処理系(の途中まで)を作ろう
Goで言語処理系(の途中まで)を作ろうEsehara Shigeo
 
Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析
Takuya Ueda
 
GAE/Goとsyncパッケージ
GAE/GoとsyncパッケージGAE/Goとsyncパッケージ
GAE/Goとsyncパッケージ
Takuya Ueda
 
今日から始める Go言語 と appengine
今日から始める Go言語 と appengine今日から始める Go言語 と appengine
今日から始める Go言語 と appengine
a know
 
メルカリアッテの実務で使えた、GAE/Goの開発を効率的にする方法
メルカリアッテの実務で使えた、GAE/Goの開発を効率的にする方法メルカリアッテの実務で使えた、GAE/Goの開発を効率的にする方法
メルカリアッテの実務で使えた、GAE/Goの開発を効率的にする方法
Takuya Ueda
 
エディタの壁を越えるGoの開発ツールの文化と作成法
エディタの壁を越えるGoの開発ツールの文化と作成法エディタの壁を越えるGoの開発ツールの文化と作成法
エディタの壁を越えるGoの開発ツールの文化と作成法
Takuya Ueda
 
Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会2
Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会2Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会2
Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会2Takuya Ueda
 
Goroutineと channelから はじめるgo言語
Goroutineと channelから はじめるgo言語Goroutineと channelから はじめるgo言語
Goroutineと channelから はじめるgo言語
Takuya Ueda
 
今日から始めるGopher - スタートGo #0 @GDG名古屋
今日から始めるGopher - スタートGo #0 @GDG名古屋今日から始めるGopher - スタートGo #0 @GDG名古屋
今日から始めるGopher - スタートGo #0 @GDG名古屋Takuya Ueda
 
Goでwebアプリを開発してみよう
Goでwebアプリを開発してみようGoでwebアプリを開発してみよう
Goでwebアプリを開発してみよう
Takuya Ueda
 
Pynyumon03 LT
Pynyumon03 LTPynyumon03 LT
Pynyumon03 LT
drillan
 
GoでMinecraftっぽいの作る
GoでMinecraftっぽいの作るGoでMinecraftっぽいの作る
GoでMinecraftっぽいの作る
京大 マイコンクラブ
 
tse - Pythonによるテキスト整形ユーティリティ
tse - Pythonによるテキスト整形ユーティリティtse - Pythonによるテキスト整形ユーティリティ
tse - Pythonによるテキスト整形ユーティリティ
Atsuo Ishimoto
 
今年使ってみて良かった、Pythonモジュール、パッケージ、ツール
今年使ってみて良かった、Pythonモジュール、パッケージ、ツール今年使ってみて良かった、Pythonモジュール、パッケージ、ツール
今年使ってみて良かった、Pythonモジュール、パッケージ、ツール
aoshiman
 
Python と型ヒント (Type Hints)
Python と型ヒント (Type Hints)Python と型ヒント (Type Hints)
Python と型ヒント (Type Hints)
Tetsuya Morimoto
 

What's hot (20)

Goとテスト
GoとテストGoとテスト
Goとテスト
 
マスター・オブ・Reflectパッケージ
マスター・オブ・Reflectパッケージマスター・オブ・Reflectパッケージ
マスター・オブ・Reflectパッケージ
 
GAE/GoでWebアプリ開発入門
GAE/GoでWebアプリ開発入門GAE/GoでWebアプリ開発入門
GAE/GoでWebアプリ開発入門
 
インタフェースの実装パターン
インタフェースの実装パターンインタフェースの実装パターン
インタフェースの実装パターン
 
条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化
 
Goで言語処理系(の途中まで)を作ろう
Goで言語処理系(の途中まで)を作ろうGoで言語処理系(の途中まで)を作ろう
Goで言語処理系(の途中まで)を作ろう
 
Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析
 
GAE/Goとsyncパッケージ
GAE/GoとsyncパッケージGAE/Goとsyncパッケージ
GAE/Goとsyncパッケージ
 
今日から始める Go言語 と appengine
今日から始める Go言語 と appengine今日から始める Go言語 と appengine
今日から始める Go言語 と appengine
 
メルカリアッテの実務で使えた、GAE/Goの開発を効率的にする方法
メルカリアッテの実務で使えた、GAE/Goの開発を効率的にする方法メルカリアッテの実務で使えた、GAE/Goの開発を効率的にする方法
メルカリアッテの実務で使えた、GAE/Goの開発を効率的にする方法
 
エディタの壁を越えるGoの開発ツールの文化と作成法
エディタの壁を越えるGoの開発ツールの文化と作成法エディタの壁を越えるGoの開発ツールの文化と作成法
エディタの壁を越えるGoの開発ツールの文化と作成法
 
Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会2
Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会2Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会2
Goroutineとchannelから始めるgo言語@初心者向けgolang勉強会2
 
Goroutineと channelから はじめるgo言語
Goroutineと channelから はじめるgo言語Goroutineと channelから はじめるgo言語
Goroutineと channelから はじめるgo言語
 
今日から始めるGopher - スタートGo #0 @GDG名古屋
今日から始めるGopher - スタートGo #0 @GDG名古屋今日から始めるGopher - スタートGo #0 @GDG名古屋
今日から始めるGopher - スタートGo #0 @GDG名古屋
 
Goでwebアプリを開発してみよう
Goでwebアプリを開発してみようGoでwebアプリを開発してみよう
Goでwebアプリを開発してみよう
 
Pynyumon03 LT
Pynyumon03 LTPynyumon03 LT
Pynyumon03 LT
 
GoでMinecraftっぽいの作る
GoでMinecraftっぽいの作るGoでMinecraftっぽいの作る
GoでMinecraftっぽいの作る
 
tse - Pythonによるテキスト整形ユーティリティ
tse - Pythonによるテキスト整形ユーティリティtse - Pythonによるテキスト整形ユーティリティ
tse - Pythonによるテキスト整形ユーティリティ
 
今年使ってみて良かった、Pythonモジュール、パッケージ、ツール
今年使ってみて良かった、Pythonモジュール、パッケージ、ツール今年使ってみて良かった、Pythonモジュール、パッケージ、ツール
今年使ってみて良かった、Pythonモジュール、パッケージ、ツール
 
Python と型ヒント (Type Hints)
Python と型ヒント (Type Hints)Python と型ヒント (Type Hints)
Python と型ヒント (Type Hints)
 

Similar to マスター・オブ・goパッケージ

Boost Fusion Library
Boost Fusion LibraryBoost Fusion Library
Boost Fusion Library
Akira Takahashi
 
20170131 python3 6 PEP526
20170131 python3 6 PEP526 20170131 python3 6 PEP526
20170131 python3 6 PEP526
masahitojp
 
「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12
「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12
「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12
Takanori Suzuki
 
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラーNode.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
mganeko
 
ECMAScript没proposal追悼式
ECMAScript没proposal追悼式ECMAScript没proposal追悼式
ECMAScript没proposal追悼式
京大 マイコンクラブ
 
関数型志向Python - LLまつり2013
関数型志向Python - LLまつり2013関数型志向Python - LLまつり2013
関数型志向Python - LLまつり2013Esehara Shigeo
 
ひのきのぼうだけで全クリ目指す
ひのきのぼうだけで全クリ目指すひのきのぼうだけで全クリ目指す
ひのきのぼうだけで全クリ目指す
AromaBlack
 
Mesh tensorflow
Mesh tensorflowMesh tensorflow
Mesh tensorflow
kuroko
 
プログラマのための文書推薦入門
プログラマのための文書推薦入門プログラマのための文書推薦入門
プログラマのための文書推薦入門
y-uti
 
2017-12-04 Linuxの基本構造とBashでの扱い方
2017-12-04 Linuxの基本構造とBashでの扱い方2017-12-04 Linuxの基本構造とBashでの扱い方
2017-12-04 Linuxの基本構造とBashでの扱い方
浩平 渡邉
 
今最もアツイdistribution Gentoo Linuxについて
今最もアツイdistribution Gentoo Linuxについて今最もアツイdistribution Gentoo Linuxについて
今最もアツイdistribution Gentoo LinuxについてTakuto Matsuu
 
研究生のためのC++ no.2
研究生のためのC++ no.2研究生のためのC++ no.2
研究生のためのC++ no.2
Tomohiro Namba
 
LLdeade Python Language Update
LLdeade Python Language UpdateLLdeade Python Language Update
LLdeade Python Language Update
Atsushi Shibata
 
Chainerの使い方と自然言語処理への応用
Chainerの使い方と自然言語処理への応用Chainerの使い方と自然言語処理への応用
Chainerの使い方と自然言語処理への応用
Seiya Tokui
 
2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ
Makiko Konoshima
 
Introduction of Python
Introduction of PythonIntroduction of Python
Introduction of Python
Tomoya Nakayama
 
スタート低レイヤー #0
スタート低レイヤー #0スタート低レイヤー #0
スタート低レイヤー #0Kiwamu Okabe
 
Play meetup-2-dev-best-practices
Play meetup-2-dev-best-practicesPlay meetup-2-dev-best-practices
Play meetup-2-dev-best-practicesk4200
 
Essential Scala 第5章 シーケンス処理
Essential Scala 第5章 シーケンス処理Essential Scala 第5章 シーケンス処理
Essential Scala 第5章 シーケンス処理
Takuya Tsuchida
 

Similar to マスター・オブ・goパッケージ (20)

Boost Fusion Library
Boost Fusion LibraryBoost Fusion Library
Boost Fusion Library
 
20170131 python3 6 PEP526
20170131 python3 6 PEP526 20170131 python3 6 PEP526
20170131 python3 6 PEP526
 
「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12
「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12
「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12
 
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラーNode.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
 
ECMAScript没proposal追悼式
ECMAScript没proposal追悼式ECMAScript没proposal追悼式
ECMAScript没proposal追悼式
 
関数型志向Python - LLまつり2013
関数型志向Python - LLまつり2013関数型志向Python - LLまつり2013
関数型志向Python - LLまつり2013
 
ひのきのぼうだけで全クリ目指す
ひのきのぼうだけで全クリ目指すひのきのぼうだけで全クリ目指す
ひのきのぼうだけで全クリ目指す
 
Mesh tensorflow
Mesh tensorflowMesh tensorflow
Mesh tensorflow
 
プログラマのための文書推薦入門
プログラマのための文書推薦入門プログラマのための文書推薦入門
プログラマのための文書推薦入門
 
2017-12-04 Linuxの基本構造とBashでの扱い方
2017-12-04 Linuxの基本構造とBashでの扱い方2017-12-04 Linuxの基本構造とBashでの扱い方
2017-12-04 Linuxの基本構造とBashでの扱い方
 
今最もアツイdistribution Gentoo Linuxについて
今最もアツイdistribution Gentoo Linuxについて今最もアツイdistribution Gentoo Linuxについて
今最もアツイdistribution Gentoo Linuxについて
 
研究生のためのC++ no.2
研究生のためのC++ no.2研究生のためのC++ no.2
研究生のためのC++ no.2
 
LLdeade Python Language Update
LLdeade Python Language UpdateLLdeade Python Language Update
LLdeade Python Language Update
 
Subprocess no susume
Subprocess no susumeSubprocess no susume
Subprocess no susume
 
Chainerの使い方と自然言語処理への応用
Chainerの使い方と自然言語処理への応用Chainerの使い方と自然言語処理への応用
Chainerの使い方と自然言語処理への応用
 
2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ
 
Introduction of Python
Introduction of PythonIntroduction of Python
Introduction of Python
 
スタート低レイヤー #0
スタート低レイヤー #0スタート低レイヤー #0
スタート低レイヤー #0
 
Play meetup-2-dev-best-practices
Play meetup-2-dev-best-practicesPlay meetup-2-dev-best-practices
Play meetup-2-dev-best-practices
 
Essential Scala 第5章 シーケンス処理
Essential Scala 第5章 シーケンス処理Essential Scala 第5章 シーケンス処理
Essential Scala 第5章 シーケンス処理
 

More from Takuya Ueda

Goにおけるバージョン管理の必要性 − vgoについて −
Goにおけるバージョン管理の必要性 − vgoについて −Goにおけるバージョン管理の必要性 − vgoについて −
Goにおけるバージョン管理の必要性 − vgoについて −
Takuya Ueda
 
WebAssembly with Go
WebAssembly with GoWebAssembly with Go
WebAssembly with Go
Takuya Ueda
 
そうだ、Goを始めよう
そうだ、Goを始めようそうだ、Goを始めよう
そうだ、Goを始めよう
Takuya Ueda
 
メルカリ カウルのマスタデータの更新
メルカリ カウルのマスタデータの更新メルカリ カウルのマスタデータの更新
メルカリ カウルのマスタデータの更新
Takuya Ueda
 
Go Friday 傑作選
Go Friday 傑作選Go Friday 傑作選
Go Friday 傑作選
Takuya Ueda
 
GoによるiOSアプリの開発
GoによるiOSアプリの開発GoによるiOSアプリの開発
GoによるiOSアプリの開発
Takuya Ueda
 
Static Analysis in Go
Static Analysis in GoStatic Analysis in Go
Static Analysis in Go
Takuya Ueda
 
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話
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
 
goパッケージで型情報を用いたソースコード検索を実現する
goパッケージで型情報を用いたソースコード検索を実現するgoパッケージで型情報を用いたソースコード検索を実現する
goパッケージで型情報を用いたソースコード検索を実現する
Takuya Ueda
 
Cloud Functionsの紹介
Cloud Functionsの紹介Cloud Functionsの紹介
Cloud Functionsの紹介
Takuya Ueda
 
Namespace API を用いたマルチテナント型 Web アプリの実践
Namespace API を用いたマルチテナント型 Web アプリの実践Namespace API を用いたマルチテナント型 Web アプリの実践
Namespace API を用いたマルチテナント型 Web アプリの実践
Takuya Ueda
 
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
Takuya Ueda
 
粗探しをしてGoのコントリビューターになる方法
粗探しをしてGoのコントリビューターになる方法粗探しをしてGoのコントリビューターになる方法
粗探しをしてGoのコントリビューターになる方法
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 (18)

Goにおけるバージョン管理の必要性 − vgoについて −
Goにおけるバージョン管理の必要性 − vgoについて −Goにおけるバージョン管理の必要性 − vgoについて −
Goにおけるバージョン管理の必要性 − vgoについて −
 
WebAssembly with Go
WebAssembly with GoWebAssembly with Go
WebAssembly with Go
 
そうだ、Goを始めよう
そうだ、Goを始めようそうだ、Goを始めよう
そうだ、Goを始めよう
 
メルカリ カウルのマスタデータの更新
メルカリ カウルのマスタデータの更新メルカリ カウルのマスタデータの更新
メルカリ カウルのマスタデータの更新
 
Go Friday 傑作選
Go Friday 傑作選Go Friday 傑作選
Go Friday 傑作選
 
GoによるiOSアプリの開発
GoによるiOSアプリの開発GoによるiOSアプリの開発
GoによるiOSアプリの開発
 
Static Analysis in Go
Static Analysis in GoStatic Analysis in Go
Static Analysis in Go
 
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話
 
オススメの標準・準標準パッケージ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の紹介
 
goパッケージで型情報を用いたソースコード検索を実現する
goパッケージで型情報を用いたソースコード検索を実現するgoパッケージで型情報を用いたソースコード検索を実現する
goパッケージで型情報を用いたソースコード検索を実現する
 
Cloud Functionsの紹介
Cloud Functionsの紹介Cloud Functionsの紹介
Cloud Functionsの紹介
 
Namespace API を用いたマルチテナント型 Web アプリの実践
Namespace API を用いたマルチテナント型 Web アプリの実践Namespace API を用いたマルチテナント型 Web アプリの実践
Namespace API を用いたマルチテナント型 Web アプリの実践
 
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
 
粗探しをしてGoのコントリビューターになる方法
粗探しをしてGoのコントリビューターになる方法粗探しをしてGoのコントリビューターになる方法
粗探しをしてGoのコントリビューターになる方法
 
GAE/GoでLINE Messaging API を使う
GAE/GoでLINE Messaging API を使うGAE/GoでLINE Messaging API を使う
GAE/GoでLINE Messaging API を使う
 

Recently uploaded

遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
t m
 
This is the company presentation material of RIZAP Technologies, Inc.
This is the company presentation material of RIZAP Technologies, Inc.This is the company presentation material of RIZAP Technologies, Inc.
This is the company presentation material of RIZAP Technologies, Inc.
chiefujita1
 
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさJSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
0207sukipio
 
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
Toru Tamaki
 
Generating Automatic Feedback on UI Mockups with Large Language Models
Generating Automatic Feedback on UI Mockups with Large Language ModelsGenerating Automatic Feedback on UI Mockups with Large Language Models
Generating Automatic Feedback on UI Mockups with Large Language Models
harmonylab
 
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
Matsushita Laboratory
 
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアルLoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
CRI Japan, Inc.
 
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
Matsushita Laboratory
 

Recently uploaded (8)

遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
 
This is the company presentation material of RIZAP Technologies, Inc.
This is the company presentation material of RIZAP Technologies, Inc.This is the company presentation material of RIZAP Technologies, Inc.
This is the company presentation material of RIZAP Technologies, Inc.
 
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさJSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
 
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
 
Generating Automatic Feedback on UI Mockups with Large Language Models
Generating Automatic Feedback on UI Mockups with Large Language ModelsGenerating Automatic Feedback on UI Mockups with Large Language Models
Generating Automatic Feedback on UI Mockups with Large Language Models
 
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
 
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアルLoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
 
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
 

マスター・オブ・goパッケージ