liyujie
2025-08-28 d9927380ed7c8366f762049be9f3fee225860833
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
 
package context_test
 
import (
   "context"
   "fmt"
   "time"
)
 
// This example demonstrates the use of a cancelable context to prevent a
// goroutine leak. By the end of the example function, the goroutine started
// by gen will return without leaking.
func ExampleWithCancel() {
   // gen generates integers in a separate goroutine and
   // sends them to the returned channel.
   // The callers of gen need to cancel the context once
   // they are done consuming generated integers not to leak
   // the internal goroutine started by gen.
   gen := func(ctx context.Context) <-chan int {
       dst := make(chan int)
       n := 1
       go func() {
           for {
               select {
               case <-ctx.Done():
                   return // returning not to leak the goroutine
               case dst <- n:
                   n++
               }
           }
       }()
       return dst
   }
 
   ctx, cancel := context.WithCancel(context.Background())
   defer cancel() // cancel when we are finished consuming integers
 
   for n := range gen(ctx) {
       fmt.Println(n)
       if n == 5 {
           break
       }
   }
   // Output:
   // 1
   // 2
   // 3
   // 4
   // 5
}
 
// This example passes a context with an arbitrary deadline to tell a blocking
// function that it should abandon its work as soon as it gets to it.
func ExampleWithDeadline() {
   d := time.Now().Add(50 * time.Millisecond)
   ctx, cancel := context.WithDeadline(context.Background(), d)
 
   // Even though ctx will be expired, it is good practice to call its
   // cancelation function in any case. Failure to do so may keep the
   // context and its parent alive longer than necessary.
   defer cancel()
 
   select {
   case <-time.After(1 * time.Second):
       fmt.Println("overslept")
   case <-ctx.Done():
       fmt.Println(ctx.Err())
   }
 
   // Output:
   // context deadline exceeded
}
 
// This example passes a context with a timeout to tell a blocking function that
// it should abandon its work after the timeout elapses.
func ExampleWithTimeout() {
   // Pass a context with a timeout to tell a blocking function that it
   // should abandon its work after the timeout elapses.
   ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond)
   defer cancel()
 
   select {
   case <-time.After(1 * time.Second):
       fmt.Println("overslept")
   case <-ctx.Done():
       fmt.Println(ctx.Err()) // prints "context deadline exceeded"
   }
 
   // Output:
   // context deadline exceeded
}
 
// This example demonstrates how a value can be passed to the context
// and also how to retrieve it if it exists.
func ExampleWithValue() {
   type favContextKey string
 
   f := func(ctx context.Context, k favContextKey) {
       if v := ctx.Value(k); v != nil {
           fmt.Println("found value:", v)
           return
       }
       fmt.Println("key not found:", k)
   }
 
   k := favContextKey("language")
   ctx := context.WithValue(context.Background(), k, "Go")
 
   f(ctx, k)
   f(ctx, favContextKey("color"))
 
   // Output:
   // found value: Go
   // key not found: color
}