У меня есть структура с именами 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 {
// ... ??
}
Я люблю идти на все, кроме этого. Спасибо
Проблема с подходом здесь заключается в том, что вы пытаетесь рассматривать встраивание как наследование на основе классов, которого Go намеренно не имеет. Переключение на использование более специфических интерфейсов, как показано ниже, является одним из способов сделать это, но также есть хороший шанс, что фактическая невыдуманная проблема не должна решаться через встраивание, которое вы также должны учитывать.

Объявите интерфейс, уникальный для каждого встроенного типа:
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
Удалите возвращаемые значения, если это не то, что вам нужно.
Боже мой, это именно то, что я искал. Очень признателен!
«Я нашел способ через модуль отражения, но это очень шумный код». --
reflectваш единственный вариант.