Я хочу создать заполнитель в объекте context
, чтобы позволить нижестоящему коду заполнять error
в контексте, чтобы при выходе из программы я мог зафиксировать окончательную ошибку, но следующий код не работает.
Я ожидаю получить адрес переменной типа error
, например указатель в стиле C на указатель, и позже заполнить адрес реальным объектом ошибки.
Может ли кто-нибудь помочь мне понять, почему это не работает так, как ожидалось?
func contextWithError_test() {
ctx := context.Background()
ctx = contextWithFinalError(ctx)
fillError(ctx)
finalError := FinalErrorFromContext(ctx)
if finalError != nil {
fmt.Println(*finalError)
}
}
func fillError(ctx1 context.Context) {
var err error = errors.New("something wrong")
finalError := FinalErrorFromContext(ctx1)
if finalError != nil {
finalError = &err
}
}
func contextWithFinalError(ctx context.Context) context.Context {
var finalError error
return context.WithValue(ctx, finalErrorKey, &finalError)
}
func FinalErrorFromContext(ctx context.Context) *error {
finalError, ok := ctx.Value(finalErrorKey).(*error)
if ok {
return finalError
}
return nil
}
PS Я уже нашел способ достичь своей цели, мне нужно объявить новый тип, чтобы обернуть ошибку:
type ErrorWrapper struct {
finalError error
}
И вставьте адрес объекта ErrorWrapper
в context
.
Но кто-нибудь знает, почему первоначальная версия не работает?
Вы делаете
finalError := FinalErrorFromContext(ctx1)
if finalError != nil {
finalError = &err
}
но, вероятно, имею в виду
finalError := FinalErrorFromContext(ctx1)
if finalError != nil {
*finalError = err
}
Вы хотите переназначать не finalError
, а переменную, на которую он указывает.
Замените
finalError = &err
на*finalError = err
(вы хотите отредактировать значение, на которое указываетfinalError
). Детская площадка.