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
740
Golang再入門
* Golangでのinterfaceの使い方
* エラーハンドリング
ques0942
June 20, 2023
Tweet
Share
Other Decks in Programming
See All in Programming
PHPer's Guide to Daemon Crafting Taming and Summoning
uzulla
2
940
安全に倒し切るリリースをするために:15年来レガシーシステムのフルリプレイス挑戦記
sakuraikotone
5
2.2k
イベントソーシングによってインピーダンスミスマッチから解放された話
tkawae
1
310
RailsでCQRS/ESをやってみたきづき
suzukimar
2
1.5k
生産性アップのためのAI個人活用
kunoyasu
0
470
Windows版PHPのビルド手順とPHP 8.4における変更点
matsuo_atsushi
0
360
PHPのガベージコレクションを深掘りしよう
rinchoku
0
240
研究開発と実装OSSと プロダクトの好循環 / A virtuous cycle of research and development implementation OSS and products
linyows
1
190
Devin入門と最近のアップデートから見るDevinの進化 / Introduction to Devin and the Evolution of Devin as Seen in Recent Update
rkaga
7
3.5k
JavaOne 2025: Advancing Java Profiling
jbachorik
1
310
マルチアカウント環境での、そこまでがんばらない RI/SP 運用設計
wa6sn
0
320
ローコードサービスの進化のためのモノレポ移行
taro28
1
330
Featured
See All Featured
BBQ
matthewcrist
88
9.5k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.4k
How GitHub (no longer) Works
holman
314
140k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
30
2.3k
It's Worth the Effort
3n
184
28k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
4
490
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
Rails Girls Zürich Keynote
gr2m
94
13k
A better future with KSS
kneath
238
17k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
117
51k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
46
2.4k
Mobile First: as difficult as doing things right
swwweet
223
9.5k
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