Избегайте дублирования кода, используя интерфейсы в качестве параметра - PullRequest
1 голос
/ 28 октября 2019

У меня есть несколько структур с общим отношением к другой структуре

type Question struct {
    ID  int `json:"id,omitempty"`
    ...
}

type EvaluationQuestion struct {
    Question   Question `json:"question" sql:"-"`
    Min        int      `json:"min"`
    Max        int      `json:"max"`
    QuestionID int      `json:"question_id,omitempty"`
}

type TextQuestion struct {
    Question   Question `json:"question" sql:"-"`
    MaxValue   int      `json:"max_value"`
    QuestionID int      `json:"question_id,omitempty"`
}

У меня также есть метод для сохранения данных в моей базе данных, который будет одинаковым для каждой структуры, только тип структуры изменится

func CreateTextQuestion(textQuestion *TextQuestion) error {
    question := textQuestion.Question

    if err := database.Db.Insert(&question); err != nil {
        return err
    }

    textQuestion.QuestionID = question.ID

    return database.Db.Insert(textQuestion)
}

Чтобы избежать дублирования кода, я попытался использовать интерфейс, который будет реализовывать методы для каждой структуры (даже если это тоже некоторое дублирование ...)

type Entity interface {
    getQuestion() Question
    questionID(int) TextQuestion
}

func (t TextQuestion) getQuestion() Question {
    return t.Question
}

func (t TextQuestion) questionID(id int) TextQuestion {
    t.QuestionID = id

    return t
}

func (e EvaluationQuestion) getQuestion() Question {
    return e.Question
}

func (e EvaluationQuestion) questionID(id int) EvaluationQuestion {
    e.QuestionID = id

    return e
}

Затем я обновил свой Create метод использования этого интерфейса

func Create(entity Entity) error {
    question := entity.getQuestion()

    if err := database.Db.Insert(&question); err != nil {
        return err
    }

    questionType := entity.questionID(question.ID)

    return database.Db.Insert(&questionType)
}

Проблема в том, что мой интерфейс не совместим с каждой структурой, поэтому я получаю ошибки компиляции, потому что ожидаемый тип возврата моего questionID метода не является правильным

api_1 |[00] handlers / choiceQuestion.go: 28: 39: невозможно преобразовать вопрос (тип models.ChoiceQuestion) в тип модели. Entity: api_1 |[00] models.ChoiceQuestion не реализует models.Entity (неправильный тип для метода models.questionID) api_1 |[00] имеют models.questionID (int) models.ChoiceQuestion api_1 |[00] хочу models.questionID (int) models.TextQuestion

Есть ли способ избежать дублирования кода при работе с несколькими структурами с Go?

Я также пробовал с переключателем типаи отражение без успеха.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...