Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Contextとはなにか

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

 Contextとはなにか

2026/06/17 GoConnect #14 で登壇した資料です。

なお、登壇中にサンプルコードⅡforループが抜けていることが発覚しています。

Avatar for chiroruxx

chiroruxx

June 17, 2026

More Decks by chiroruxx

Other Decks in Programming

Transcript

  1. みんな知ってる Context // GetUser はユーザを返す func (s *UserService) GetUser( ctx

    context.Context, id uint, ) (*User, error) { return s.repository.FindByID(ctx, id) } 引数で受け取って 引数にわたす Contextって一体なんなんだ!?
  2. 公式によると – “A Context carries a deadline, a cancellation signal,

    and other values across API boundaries. ” – コンテキストは、期限、キャンセルシグナル、およびその他の値 をAPI境界を越えて伝達します。 – なるほどわからん
  3. 呼び出し時に データを引数で 渡す conn, err := listener.Accept() for { if

    err != nil { log.Print(err) continue } go handleConn(conn) }
  4. パッケージ変数 を使う package bank import "sync" var ( mu sync.Mutex

    balance int ) // Balance は残高を取得する func Balance() int { mu.Lock() defer mu.Unlock() return balance } // Deposit は預金する func Deposit(amount int) { mu.Lock() defer mu.Unlock() balance += amount }
  5. チャネルを経由 して渡す // pooling は1秒ごとにファイルに変更がないかチェックする func pooling(done chan struct{}) error

    { cache, err := getFile() if err != nil { return err } tick := time.Tick(1 * time.Second) select { case <-done: fmt.Println("cancelled") return nil case <-tick: f, err := getFile() if err != nil { return err } if !f.equals(cache) { fmt.Println("file is changed!") break } } return nil }
  6. チャネルを経由 して渡す done = make(chan struct{}) go func() { err

    := pooling(done) if err != nil { log.Print(err) } }() // ...do something close(done)
  7. Contextの 使い⽅ // pooling は1秒ごとにファイルに変更がないかチェックする func pooling(ctx context.Context) error {

    cache, err := getFile() if err != nil { return err } tick := time.Tick(1 * time.Second) select { case <-ctx.Done(): fmt.Println("cancelled") return nil case <-tick: f, err := getFile() if err != nil { return err } if !f.equals(cache) { fmt.Println("file is changed!") break } } return nil }
  8. Contextの 使い⽅ ctx := context.Background() ctx, cancel := context.WithCancel(ctx) go

    func() { err := pooling(ctx) if err != nil { log.Print(err) } }() // ...do something cancel()
  9. 歴史的経緯 – Context は Sameer Ajmani氏による “Go Concurrency Patterns: Context”が元

    – Go サーバにおいて – ハンドラはリクエスト固有の値にアクセスする必要があるが – いつリクエストを完了、タイムアウト、キャンセルさせるべきか? – このデザインパターンが golang.org/x/net/context に入る – Go サーバの話だったので net パッケージ – 標準化された context パッケージになった
  10. 再掲: みんな知ってる Context // GetUser はユーザを返す func (s *UserService) GetUser(

    ctx context.Context, id uint, ) (*User, error) { return s.repository.FindByID(ctx, id) } 引数で受け取って 引数にわたす