Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Golang再入門
Search
ques0942
June 20, 2023
Programming
0
710
Golang再入門
* Golangでのinterfaceの使い方
* エラーハンドリング
ques0942
June 20, 2023
Tweet
Share
Other Decks in Programming
See All in Programming
Package Traits
ikesyo
1
150
PHPで作るWebSocketサーバー ~リアクティブなアプリケーションを知るために~ / WebSocket Server in PHP - To know reactive applications
seike460
PRO
2
720
htmxって知っていますか?次世代のHTML
hiro_ghap1
0
400
Compose UIテストを使った統合テスト
hiroaki404
0
120
責務を分離するための例外設計 - PHPカンファレンス 2024
kajitack
9
2.3k
歴史と現在から考えるスケーラブルなソフトウェア開発のプラクティス
i10416
0
260
PSR-15 はあなたのための ものではない? - phpcon2024
myamagishi
0
360
Cloudflare MCP ServerでClaude Desktop からWeb APIを構築
kutakutat
1
630
コンテナをたくさん詰め込んだシステムとランタイムの変化
makihiro
1
180
PHPとAPI Platformで作る本格的なWeb APIアプリケーション(入門編) / phpcon 2024 Intro to API Platform
ttskch
0
360
どうして手を動かすよりもチーム内のコードレビューを優先するべきなのか
okashoi
3
820
Stackless и stackful? Корутины и асинхронность в Go
lamodatech
0
1.2k
Featured
See All Featured
The Art of Programming - Codeland 2020
erikaheidi
53
13k
Agile that works and the tools we love
rasmusluckow
328
21k
Optimising Largest Contentful Paint
csswizardry
33
3k
Building Adaptive Systems
keathley
38
2.3k
Put a Button on it: Removing Barriers to Going Fast.
kastner
59
3.6k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
2
160
jQuery: Nuts, Bolts and Bling
dougneiner
62
7.6k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
26
1.9k
YesSQL, Process and Tooling at Scale
rocio
170
14k
The Cost Of JavaScript in 2023
addyosmani
46
7.2k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
Making Projects Easy
brettharned
116
6k
Transcript
1 Golang再入門 mercari.go #22
2 自己紹介 • twitter: @ques0942 • mercariのバックエンドエンジニア • 最近の主戦場はPHPで、mercariの取引機能を担当するチームで働いています •
1年半ほど前まではGolangがメインで、最近Golangに再入門しました
3 今日話すこと • Golang再入門するときに勉強し直したこと、変化を認識したことの紹介 ◦ 初心者向けの内容です • 目次 ◦ 構造的部分型(Golangのインターフェースの使い方
) ◦ エラーハンドリング
4 構造的部分型(Golangのインターフェースの使い方) • PHPなどの公称型とは異なる型システム ◦ クラスではなくインターフェースに基づいて型チェックがなされる ◦ Pythonのduck typingを静的に行うようなもの ◦
継承、抽象クラスは無いが、構造体を埋め込んで機能を流用することは可能 • Golang(とかTypeScriptとかClean architecture)に慣れると「機能を使う側が インターフェースを定義する」という感覚になった ◦ Javaでコードを書いていたときは、インターフェースは実装しているクラスの付属物だと思っていた ▪ クラスを作る側がインターフェースを定義する ◦ “Accept interfaces, return structs” とか github/goのwikiにあるレビュー指針 とかを参考に するとインターフェースは呼び出す側のものとして整理されている
5 構造的部分型(Golangのインターフェースの使い方) • 例えばAPIを書くとして、あるリクエストをコントローラーが処理するときにストレージ への読み込み、書き込みが発生する • このストレージのインターフェースはコントローラーとデータストア、どちらのレイヤー が定義する? • サンプルコード
6 構造的部分型(Golangのインターフェースの使い方) • 例えば以下のようなパッケージ構 成のとき ◦ cmd/main.go ◦ controller/controller.go ◦
storage/storage.go • 右のインターフェースはどこに置く? type StringStorage interface { Load(key string) (string, error) Store(key, value string) error }
7 構造的部分型(Golangのインターフェースの使い方) package controller type StringStorage interface { Load(key string)
(string, error) Store(key, value string) error } type Controller struct { s StringStorage } func New(s StringStorage) *Controller { return &Controller{s: s} } func (c *Controller) Load(key string) (string, error) { return c.s.Load(key) } func (c *Controller) Store(key, value string) error { return c.s.Store(key, value) } • 今のところインター フェースを利用する controllerパッケージ に置くのが良いと思って います
8 構造的部分型(Golangのインターフェースの使い方) • 依存する機能(メソッド)が明確になる ◦ 例えばStringStorageにReplace(key, value)みたいな機能が増えても、 Controllerはその機能 を使うまではインターフェースを変更する必要がない ◦
インターフェースに含まれない関数は利用されないので、機能改修時に影響範囲調査が楽になる • 抽象度の高い方から実装できる ◦ ユースケースに近いところから実装 ▪ 必要なインターフェースを定義 • ストレージとかAPIクライアントをそのインターフェースに合うように実装 ◦ 契約駆動開発(Contract Driven Development)味がある ◦ 結局うまく実装できなくて抽象度の高い側を直す羽目になったりもしますが
9 エラーハンドリング • 昔はpkg/errorsで良かったけど今は? • 欲しい機能 ◦ 任意のエラーを定義して何が起きたかを特定したい ◦ スタックトレースを取得して、意図しないエラーがどこでどのように発生したか特定したい
• 検討した候補 ◦ errors.New + fmt.Errorf ▪ golang1.13からの機能 ▪ スタックトレースを保存する機能がない ◦ pkg/errors ▪ おなじみだがアーカイブされた ◦ morikuni/failure ▪ mercari社内で利用実績あり
10 エラーハンドリング
11 欲しい機能(独自エラー) • アプリケーション独自のエラーを定義したい ◦ 例えば ▪ UserNotFoundError ▪ PermissionDeniedError
▪ InvalidValueError • なぜ? ◦ アプリケーションでどんなトラブルが起きたか知りたい ◦ 適切なエラーハンドリングがしたい ▪ 発生したエラーを識別して、ユーザーに伝える or 適切な緩和処置をしたい
12 欲しい機能(スタックトレース) • エラーには発生したときのスタックトレースが入っていてほしい • なぜ? ◦ エラーテキストは考慮漏れで重複する可能性が有り得る ◦ どのような経路で呼び出されたか知りたい
13 現時点での私の結論 • アプリケーションで利用するなら ◦ morikuni/failure or pkg/errors ▪ どちらも任意のエラーコード定義とスタックトレースの取得が可能
▪ 個人的には • 仕事ではmorikuni/failures • 個人開発では使い慣れた pkg/errorsという感じ ▪ pkg/errorsはアーカイブされたとはいえそんなに機能追加がいるものでは無いので … • と思っていたらgo1.20でerrorsに複数エラーをラップできる 新機能が • スタックトレースが要らないなら ◦ errors.New + fmt.Errorf