Значение в контексте в Go
Контекст умеет хранить одну пару ключ и значение на каждый слой. Новый слой не затирает чужие ключи выше по цепочке, но ищет значение от текущего узла к корню, пока ключ не найдется.
Ключ лучше объявить своим пустым типом структуры, а не строкой. Тогда другой пакет не сможет случайно использовать тот же текст ключа и переписать ваши данные в общем контексте.
Заведем тип ключа, положим идентификатор запроса и прочитаем его во вложенной функции:
package main
import (
"context"
"fmt"
)
type requestIDKey struct{}
func printID(ctx context.Context) {
id := ctx.Value(requestIDKey{})
fmt.Println(id)
}
func main() {
ctx := context.WithValue(
context.Background(),
requestIDKey{},
"req-7",
)
printID(ctx)
}
На экране "req-7". Значение
достали по тому же ключу, что использовали
при записи.
Дочерний контекст видит значение родителя, если сам не переопределил этот ключ:
package main
import (
"context"
"fmt"
)
type traceKey struct{}
func main() {
parent := context.WithValue(
context.Background(),
traceKey{},
"a",
)
child, cancel := context.WithCancel(parent)
defer cancel()
fmt.Println(child.Value(traceKey{}))
}
Дан следующий код:
type userKey struct{}
ctx := context.Background()
Положите в ctx имя "ann"
по userKey и выведите его через
Value.
Скажите, почему для ключа не стоит
брать строку "user" в библиотеке,
которую подключают другие команды.
Дан следующий код:
type tagKey struct{}
base := context.WithValue(
context.Background(),
tagKey{},
"old",
)
over := context.WithValue(base, tagKey{}, "new")
Выведите значение по tagKey из
over и из base.