Утверждение типа с вложенными типами - PullRequest
0 голосов
/ 09 июня 2018
type BizError struct {
    Code string
    Mesg string
}

type ApiReply struct {
    Err BizError
}

type GetDataReply struct {
    Data interface{}
    ApiReply
}

с приведенным выше определением, я хочу сделать следующее:

func Func1(data interface{}) {
    switch data.(type) {
    case ApiReply:
        data.(ApiReply).Err.Code = "0"
    }
}

Ключевая проблема заключается в том, что в Func1 переключатель типа не знает какие-либо новыетипы, которые встраивают ApiReply, это «универсальный» обработчик.В то время как data, переданный ему, фактически является «дочерним классом» ApiReply.По-видимому, в Go вы не можете присвоить тип GetDataReply для ApiReply.

Как я могу обработать этот случай, чтобы в Func1 мне не нужно было иметь все возможные структуры, которые могут встраивать ApiReply, явно объявленный?

1 Ответ

0 голосов
/ 09 июня 2018

Вы пытаетесь внедрить систему стилей наследования в go.Структурное вложение не является наследованием и не должно рассматриваться или рассматриваться как таковое.Это анти-паттерн на ходу и, как правило, он не работает так, как вы бы этого хотели или ожидаете.

Вместо этого, более идиоматическим подходом к этому будет определение интерфейса (или пары интерфейсов) и получение вашего ответаТипы реализуют необходимые методы для соответствия.

type ApiReply interface {
    Status() (string, string)

    Body() (io.Reader, error)
}

type BizError struct {
    Code string
    Mesg string
}

func (b BizError) Status() (string, string) {
    return b.Code, b.Mesg
}

func (b BizError) Body() (io.Reader, error) {
    return nil, errors.New("BizError never contains a body")
}

Затем вы реализуете ApiReply для других структур типов ответов.Я, конечно, догадываюсь о том, что вам на самом деле нужно здесь, но, надеюсь, это поможет понять.

И если вы обнаружите, что должны это сделать, теперь вы можете выполнить переключение типов против экземпляра ApiReply, который вы получаете, и специальногоcase любые базовые типы, если это абсолютно необходимо.

...