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
790
Golang再入門
* Golangでのinterfaceの使い方
* エラーハンドリング
ques0942
June 20, 2023
Tweet
Share
Other Decks in Programming
See All in Programming
システム成長を止めない!本番無停止テーブル移行の全貌
sakawe_ee
1
220
新メンバーも今日から大活躍!SREが支えるスケールし続ける組織のオンボーディング
honmarkhunt
5
8.2k
状態遷移図を書こう / Sequence Chart vs State Diagram
orgachem
PRO
2
170
Google Agent Development Kit でLINE Botを作ってみた
ymd65536
2
260
PipeCDのプラグイン化で目指すところ
warashi
1
290
PHPでWebSocketサーバーを実装しよう2025
kubotak
0
310
ISUCON研修おかわり会 講義スライド
arfes0e2b3c
1
460
The Evolution of Enterprise Java with Jakarta EE 11 and Beyond
ivargrimstad
0
180
20250628_非エンジニアがバイブコーディングしてみた
ponponmikankan
0
710
NEWT Backend Evolution
xpromx
1
110
顧客の画像データをテラバイト単位で配信する 画像サーバを WebP にした際に起こった課題と その対応策 ~継続的な取り組みを添えて~
takutakahashi
1
310
iOS 26にアップデートすると実機でのHot Reloadができない?
umigishiaoi
0
140
Featured
See All Featured
Reflections from 52 weeks, 52 projects
jeffersonlam
351
21k
BBQ
matthewcrist
89
9.7k
Into the Great Unknown - MozCon
thekraken
40
1.9k
Fireside Chat
paigeccino
37
3.5k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
8
830
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
34
5.9k
How to train your dragon (web standard)
notwaldorf
96
6.1k
Balancing Empowerment & Direction
lara
1
440
Code Reviewing Like a Champion
maltzj
524
40k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
47
9.6k
Writing Fast Ruby
sferik
628
62k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
8
700
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