package main import ( "context" "fmt" "net/http" ) // 本函数演示如何将数据附加到上下文 func func1(ctx context.Context) { // 继续将数据(key/value)附加到上下文 ctx = context.WithValue(ctx, "name", "张三") ctx = context.WithValue(ctx, "gender", "男") ctx = context.WithValue(ctx, "age", 18) // 重要说明:该数字是int类型,不是int64类型,类型断言时要注意 // 继续将上下文作为参数传递 func2(ctx) } // 本函数演示如何从上下文里取出数据 func func2(ctx context.Context) { // 从上下文取出数据 writer, _ := ctx.Value("writer").(http.ResponseWriter) // Value()方法返回值是any类型,需要类型断言才能使用 name, _ := ctx.Value("name").(string) // Value()方法返回值是any类型,需要类型断言才能使用 gender, _ := ctx.Value("gender").(string) // Value()方法返回值是any类型,需要类型断言才能使用 age, _ := ctx.Value("age").(int) // Value()方法返回值是any类型,需要类型断言才能使用 // 在页面上输出内容 str := fmt.Sprintf("俺叫%s(%s),今年%d岁。", name, gender, age) _, _ = writer.Write([]byte(str)) // 俺叫张三(男),今年18岁。 } func main() { // 演示地址:http://localhost:8080/demo.html http.HandleFunc("/demo.html", func(writer http.ResponseWriter, request *http.Request) { requestContext := request.Context() // 获取本次请求的上下文 // requestContext := context.Background() // 也可以不使用本次请求的上下文,而是创建一个非nil的空上下文 // 将数据(key/value)附加到上下文 requestContext = context.WithValue(requestContext, "writer", writer) requestContext = context.WithValue(requestContext, "request", request) // 将上下文作为参数传递 func1(requestContext) }) // 启动HTTP服务器 err := http.ListenAndServe(":8080", nil) if err != nil { panic("启动HTTP服务器失败:" + err.Error()) } } // ========== 总结 ========== // // 1、将数据附加到上下文:ctx = context.WithValue(ctx, "key", "value"),value的数据类型为any,故可附加任意数据类型到上下文。 // 2、从上下文里取出数据;value := ctx.Value("key"),方法返回值是any类型,故如有需要可使用类型断言。 // 3、Go官方建议如果自定义函数的形参有context.Context类型,那么该参数应该放在第一位,且参数名通常为ctx,如下面的代码: // func DoSomething(ctx context.Context, arg Arg) error { // // ... use ctx ... // }
Copyright © 2024 码农人生. All Rights Reserved