Как проверить, содержит ли структура другую структуру в Go?

У меня есть структура с именами Car и Motorbike, которые представляют собой композиции с другими структурами. Например:

type HasSeats struct {
  ...
}

type HasDoors struct {
   ...
}

type Car {
   HasSeats
   HasDoors
}

type Motorbike {
   HasSeats
}

Теперь у меня есть экземпляр Car и Motorbike. Как проще всего узнать, принадлежат ли экземпляры к типу, у которого есть HasSeats и HasDoors? Я нашел способ через модуль reflect, но это очень шумный код. Любая помощь высоко ценится.

func CheckIfObjectHasDoors(carOrBike interface{}) bool {
    // ... ??
}

«Я нашел способ через модуль отражения, но это очень шумный код». -- reflect ваш единственный вариант.

mkopriva 20.07.2023 15:40

Я люблю идти на все, кроме этого. Спасибо

Daniel Stephens 20.07.2023 15:43

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

JimB 20.07.2023 16:21
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
0
3
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Объявите интерфейс, уникальный для каждого встроенного типа:

type Seats interface{ Seats() *HasSeats }
type Doors interface{ Doors() *HasDoors }

Реализуйте интерфейс для каждого из типов:

func (x *HasSeats) Seats() *HasSeats { return x }
func (x *HasDoors) Doors() *HasDoors { return x }

Используйте утверждения типа, чтобы определить, содержит ли составной тип один из встроенных типов:

var mb interface{} = &Motorbike{}
if _, ok := mb.(Seats); ok {
    fmt.Println("mb has seats")
}
if _, ok := mb.(Doors); !ok {
    fmt.Println("mb does not have doors")
}

https://go.dev/play/p/UeXgQoYu5tr

Методы интерфейса объявляются приемником, потому что кажется вероятным, что приложению потребуется прямой доступ к значению. Пример:

type HasSeats struct {
    Color string
}

...

var mb interface{} = &Motorbike{HasSeats: HasSeats{Color: "red"}}
if s, ok := mb.(Seats); ok {
    fmt.Println("mb has seats and the seat color is", s.Seats().Color)
}

https://go.dev/play/p/DsCpoW4HsUI

Удалите возвращаемые значения, если это не то, что вам нужно.

Боже мой, это именно то, что я искал. Очень признателен!

Daniel Stephens 20.07.2023 16:01

Другие вопросы по теме