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
670
Golang再入門
* Golangでのinterfaceの使い方
* エラーハンドリング
ques0942
June 20, 2023
Tweet
Share
Other Decks in Programming
See All in Programming
Googleのテストサイズを活用したテスト環境の構築
toms74209200
0
270
開発効率向上のためのリファクタリングの一歩目の選択肢 ~コード分割~ / JJUG CCC 2024 Fall
ryounasso
0
360
Server Driven Compose With Firebase
skydoves
0
390
デプロイを任されたので、教わった通りにデプロイしたら障害になった件 ~俺のやらかしを越えてゆけ~
techouse
52
32k
組織に自動テストを書く文化を根付かせる戦略(2024秋版) / Building Automated Test Culture 2024 Autumn Edition
twada
PRO
10
4.5k
Kaigi on Rails 2024 - Rails APIモードのためのシンプルで効果的なCSRF対策 / kaigionrails-2024-csrf
corocn
5
3.3k
GCCのプラグインを作る / I Made a GCC Plugin
shouth
1
150
hotwire_or_react
harunatsujita
8
4k
PagerDuty を軸にした On-Call 構築と運用課題の解決 / PagerDuty Japan Community Meetup 4
horimislime
1
110
Identifying User Idenity
moro
6
7.7k
とにかくAWS GameDay!AWSは世界の共通言語! / Anyway, AWS GameDay! AWS is the world's lingua franca!
seike460
PRO
1
530
プロジェクト新規参入者のリードタイム短縮の観点から見る、品質の高いコードとアーキテクチャを保つメリット
d_endo
1
1k
Featured
See All Featured
Imperfection Machines: The Place of Print at Facebook
scottboms
264
13k
How to Think Like a Performance Engineer
csswizardry
19
1.1k
GraphQLの誤解/rethinking-graphql
sonatard
66
9.9k
Done Done
chrislema
181
16k
The Power of CSS Pseudo Elements
geoffreycrofte
72
5.3k
Faster Mobile Websites
deanohume
304
30k
Building Better People: How to give real-time feedback that sticks.
wjessup
363
19k
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
5 minutes of I Can Smell Your CMS
philhawksworth
202
19k
Git: the NoSQL Database
bkeepers
PRO
425
64k
Building a Modern Day E-commerce SEO Strategy
aleyda
38
6.9k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
27
1.9k
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