Структурное встраивание - вот как предпочитает go lang Идея композиции лучше наследования.
https://golang.org/doc/effective_go.html#embedding
Вы должны объявить интерфейс для Транспортного средства, и все Транспортные средства реализуют этот интерфейс.
Это проблема уровня проектирования, а не просто исправление ошибки. Поскольку не совсем понятно, как именно вы собираетесь использовать и бороться с транспортными средствами. Я сделаю некоторые предположения.
Путем встраивания следует встраивать повторно используемую структуру в определенные структуры.
type VehicleTypeGeneral struct {
Id int
Name string
Milage int
}
//Embed VehicleTypeGeneral
type VehicleTypeHatchback struct {
VehicleTypeGeneral
Is4WheelDriveEnabled bool
}
Если мы создаем экземпляр vh из VehicleTypeHatchback
, тогда мы можем получить доступ к полям VehicleTypeHatchback
, а также к встроенной структуре VehicleTypeGeneral
, такой как vh.Is4WheelDriveEnabled
и vh.VehicleTypeGeneral.Name
Если VehicleTypeGeneral
реализует интерфейс, такой как Vehicle
interface, то VehicleTypeHatchback
также реализует это. Вы можете переопределить, реализовав методы.
Я добавил пример проверки типа в функции processSpecificVehicle
. Однако эти вещи замедляют выполнение. Вместо этого попробуйте использовать подходы, упомянутые в processVehicle
и processAbsVehicle
Также интерфейсы не должны иметь много методов. Одного или двух достаточно, в противном случае это нарушение принципа разделения интерфейса. Сохраняйте интерфейсы короткими и осмысленными и проектируйте их с точки зрения потребителя интерфейсов.
Полный пример с некоторыми допущениями:
package main
import "fmt"
type Vehicle interface {
GetId() int
GetName() string
}
type AbsVehicle interface {
IsAbsEnabled() bool
}
type VehicleTypeGeneral struct {
Id int
Name string
Milage int
}
func (v *VehicleTypeGeneral) GetId() int{
return v.Id
}
func (v *VehicleTypeGeneral) GetName() string{
return v.Name
}
type VehicleTypeSedan struct {
VehicleTypeGeneral
IsABSEnabled bool
}
func(vs *VehicleTypeSedan) IsAbsEnabled() bool {
return vs.IsABSEnabled
}
type VehicleTypeHatchback struct {
VehicleTypeGeneral
Is4WheelDriveEnabled bool
}
func main() {
println("Hello")
var vehicle = VehicleTypeSedan{IsABSEnabled: true, VehicleTypeGeneral: VehicleTypeGeneral{Id:1001,Name:"Sedan 1", Milage:12}}
processVehicle(&vehicle)
processAbsVehicle(&vehicle)
processSpecificVehicle(&vehicle)
processSedan(&vehicle)
}
func processVehicle(vehicle Vehicle){
println(vehicle.GetId())
println(vehicle.GetName())
}
func processAbsVehicle(vehicle AbsVehicle){
println(vehicle.IsAbsEnabled())
}
func processSpecificVehicle(vehicle Vehicle){
switch v := vehicle.(type) {
case *VehicleTypeSedan:
fmt.Printf("Its a sedan %v with ABS %v ", v.GetName(), v.IsAbsEnabled())
case *VehicleTypeHatchback:
fmt.Printf("Its a VehicleTypeHatchback %v", v.GetName())
default:
fmt.Printf("Its a Vehicle")
}
}
func processSedan(vs *VehicleTypeSedan){
println("\nprocess sedan")
println(vs.VehicleTypeGeneral.Name)
println(vs.IsABSEnabled)
}