gopher fest 2017参加レポート
TRANSCRIPT
Gopher Fest 2017参加レポート
2017/06/01(木)golang.tokyo #6
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.
自己紹介
メルカリ/ソウゾウ
上田拓也twitter: @tenntenn■ コミュニティ活動
Google Cloud Platform User Group (GCPUG) TokyoGoビギナーズgolang.tokyoGo Conference
■ 業務GAE/Goでメルカリカウルを作ってます
GoやGCPコミュニティを盛り上げる仕事
Gopherを描く仕事(LINEスタンプ)
2
3
Gopher Fest 2017に参加しました
http://tech.mercari.com/entry/gopherfest2017_report
Gopher Festとは?
● Google I/Oに合わせて開催されるイベント● 5/15にサンフランシスコで開催
○ イベントページ
● 主催はGoSF● 発表者が豪華
4
セッション一覧
● The State of Go / Francesc Campoy○ 8月リリース予定のGo1.9に関するセッション
● Event Sourcing – Architectures and Patterns / Matt Ho○ イベントソーシングをどうGoで扱うか
● Upspin / Rob Pike○ upspinの話
● Adding Context to NATS / Waldemar Quevedo○ NATSにおいてどうContextを導入していったかという話
5
The State of Go
6
https://talks.golang.org/2017/state-of-go-may.slide
リファクタリング
● 安全にリファクタリングには?○ Codebase Refactoring (with help from Go) by rsc
13
新APIの追加 コードの変更 旧APIの削除
現状のGoで簡単にできるのか?
定数の場合14
package status
const OK = http.StatusOK
STEP-1: 新APIの追加
■ statusパッケージを追加してみる
if res.StatusCode != http.StatusOK {
STEP-2: コードの変更
if res.StatusCode != status.OK {
STEP-3: 旧APIの削除 問題なし!
関数の場合15
func DoGet(url string) (*http.Response, error) {
return Get(url)
}
STEP-1: 新APIの追加
■ http.Getをリネームする
res, err := http.Get("https://golang.org")
STEP-2: コードの変更
res, err := http.DoGet("https://golang.org")
STEP-3: 旧APIの削除 問題なし!
型の場合16
type Applicant Client
STEP-1: 新APIの追加
■ http.Clientをリネームする
● メソッドが引き継げない● キャストはできる
【方法1】型を作ってみる
type Applicant struct { Client }
【方法2】埋め込んでみる
● メソッドは引き継げる● キャストができない
Alias Declarations
■ 型のエイリアスを定義できる● 完全に同じ型● キャスト不要● エイリアスの方ではメソッド定義はできない
17
type Applicant = http.Client
■ %Tは同じ元の型名を出す
type Applicant = http.Client
func main() {
fmt.Printf("%T", Applicant{})
}http.Client
math/bits
■ ビット演算に便利なライブラリ
● #18616 にて提案● http://tip.golang.org/pkg/math/bits/● LenXX, OnesCountXX● ReverseXX, ReverseBytesXX● RotateLeftXX● LeadingZerosXX, TrailingZerosXX
21
fmt.Printf("%d (%b) has %d bits set to one\n", n, n, bits.OnesCount(n))
fmt.Printf("%d reversed is %d\n", n, bits.Reverse(n))
fmt.Printf("%d can be encoded in %d bits\n", n, bits.Len(n))
sync.Map
■ スレッドセーフなマップ
● #18177 にて提案
● http://tip.golang.org/pkg/sync/#Map● ゼロ値で使える
22
sync.Mapのサンプル23
var m sync.Map
for i := 0; i < 3; i++ { go func(i int) { for j := 0; ; j++ { m.Store(i, j) } }(i)}
for i := 0; i < 10; i++ { m.Range(func(key, value interface{}) bool { fmt.Printf("%d: %d\t", key, value) return true }) fmt.Println() time.Sleep(time.Second)}
html/templateがより安全に24
type Foo struct{ Bar string }func main() { tmpl, err := template.New("home").Parse(` <a title={{.Bar | html}}> `) if err != nil { log.Fatalf("could not parse: %v", err) } foo := Foo{"haha onclick=evil()"} if err := tmpl.Execute(os.Stdout, foo); err != nil { log.Fatalf("could not execute: %v", err) }}
■ 以下のコードでエラーが起きるようになった
os.Exec
■ 重複する環境変数を削除するように
● 一番うしろのものを優先する
25
func main() {cmd := exec.Command("./getenv", "foo")cmd.Env = append(os.Environ(), "foo=newbar")cmd.Stdout = os.Stdoutcmd.Stderr = os.Stderrif err := cmd.Run(); err != nil {
log.Fatal(err)}
}
コンパイラのエラーメッセージの改善29
package mainfunc main(){ fmt.Println("that ain't gonna compile")}
fail/main.go:4: syntax error: unexpected semicolon or newline before {
fail/main.go:3:6: missing function body for "main"
fail/main.go:4:1: syntax error: unexpected semicolon or newline before {
Go1.8
Go1.9
コンパラの速度改善
● リファクタによって改善
● 一部を並行処理を採用することで改善
○ https://golang.org/issue/17639
30
go testの改善
■ 複数パッケージの場合にvendorを無視
● https://golang.org/issue/19090
31
$ go test ./...
■ テスト関数一覧が出せるように
● https://golang.org/issue/17209
$ go test -test.list .TestIntegrationTestEmbedStreamsTestEmbedFiles
go doc
■ フィールドにリンクが貼れるようになった
● https://golang.org/issue/16753● https://tip.golang.org/pkg/net/http/#Client.
Transport
32
Thank you!
twitter: @tenntenn Qiita: tenntennconnpass: tenntenn
33