Загрузка…
Загрузка…
Go · junior · сложность 2
В context.WithValue ключ должен быть сопоставимым, но, что наиболее важно, он должен быть уникальным в пределах вашего приложения и пространства зависимостей. Именно поэтому рекомендуется использовать свои собственные (нестандартные) типы ключей вместо общепринятых string.
string:Разные пакеты могут случайно использовать одну и ту же строку ("userID",
"request_id" и т. д.).
Значение в контексте будет перезаписано или «затенено» другим. package.
Получите тихие, трудно воспроизводимые ошибки маршрутизации/аутентификации/входа в систему.
Создает в пакете тип закрытого ключа, например: type ctxKey struct{} or type ctxKey int.
Внешний код не может случайно использовать один и тот же тип и значение ключа.
Таким образом, пространство имен ключей становится изолированным на уровне типичного system.
struct{}:Легкий маркер без полезной нагрузки.
Подчеркивает, что важна личность ключа, а не его «данные».
Хорошо соответствует идиоме «локальный уникальный ключ пакета».
Объявите ключи как неэкспортируемые переменные пакета.
Не используйте «пустые» строки в качестве ключей для WithValue.
Храните в Context только данные службы на уровне запроса, а не бизнес-параметры.
Нестандартные типы ключей в context.WithValue представляют собой типобезопасный механизм пространства имен. Они надежно снижают риск коллизий между пакетами и делают контекстные значения предсказуемыми в больших базах кода.
type requestIDKey struct{}
func withRequestID(ctx context.Context, id string) context.Context {
return context.WithValue(ctx, requestIDKey{}, id)
}
func requestID(ctx context.Context) (string, bool) {
v, ok := ctx.Value(requestIDKey{}).(string)
return v, ok
}В context.WithValue ключ должен быть сопоставимым, но, что наиболее важно, он должен быть уникальным в пределах вашего приложения и пространства зависимостей.