github.com/code-reading/golang@v0.0.0-20220303082512-ba5bc0e589a3/coding/context/WithCancel.go (about)

     1  package main
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  )
     7  
     8  /*
     9  	需求,构建一个数字生成器;
    10  	调用方控制生成数字个数,结束时候,调用方告知生成器停止生成数字
    11  */
    12  
    13  func main() {
    14  	// 使用闭包构建一个生成器
    15  	// 返回一个只读的int类型的channel
    16  	gen := func(ctx context.Context) <-chan int {
    17  		dst := make(chan int)
    18  		n := 1
    19  		go func() {
    20  			for {
    21  				select {
    22  				case <-ctx.Done():
    23  					return // 返回,防止goroutine泄露
    24  				default:
    25  					dst <- n
    26  					n++
    27  				}
    28  			}
    29  		}()
    30  		return dst
    31  	}
    32  	ctx, cancel := context.WithCancel(context.Background())
    33  	defer cancel()
    34  	for i := range gen(ctx) {
    35  		fmt.Println(i)
    36  		if i == 5 {
    37  			break
    38  		}
    39  	}
    40  }
    41  
    42  /*
    43  output:
    44  1
    45  2
    46  3
    47  4
    48  5
    49  */