jamesmstone
jamesmstone

Reputation: 397

Array of Go structs with the same anonymous filed, but different types

If you imagine I have the following declarations:

type Car struct {
    Vehicle
    engineType string
}

type Bus struct {
    Vehicle
    public     bool
    engineType string
}

type Bike struct {
    Vehicle
    motorbike bool
}

type Vehicle struct {
    NumberWheels     int
    NumberPassengers int
    Owner            string
}

type Vehicles []Vehicle

Playground

I'm trying to have an array of Vehicles. However this is not possible as they each have a different type ( i.e Car, Bus, Bike, etc...)

var myCar = Car{Vehicle{4, 4, "Me"}, "Manual"}
var myBike = Bike{Vehicle{2, 0, "Bob and I"}, false}
var myVehicles = Vehicles{myCar, myBike}
for i := range myVehicles {
    fmt.Println(myVehicles[i])
}

Playground

How would you achieve something like this. Or am I trying to tackle this problem from the wrong angle. I'm new to Go.

Upvotes: 1

Views: 279

Answers (1)

evanmcdonnal
evanmcdonnal

Reputation: 48076

Vehicle is embedded in Car and Bus so you got things going in the wrong direction... It's not like Vehicle is a parent class so you can't get the polymorphic behavior you're looking for out of this design. What you need is an interface.

To show you a working example I'm just going to use empty interface (it will allow you to store any type in the collection). For your actual program you might want to make something like an IVehicle interface and put whatever common method all the vehicles will have on it, maybe something like Start() or whatever...

https://play.golang.org/p/iPJbFYlo7o

To expand on that embedding thing a little bit... This isn't inheritance. You can accomplish the same things with it however the statement "Car is a Vehicle" is not true. This is actually more like composition, "Car has a Vehicle". It's just that Vehicle's fields and methods are 'hoisted' up to Car, meaning they can be accessed from an instance of Car without another layer of indirection like Car.Vehicle.FieldOnVehicle. That's not really what you're looking for. If you want to say "Car is a Vehicle" and it be true, then Vehicle needs to be an interface which Car implements.

Upvotes: 2

Related Questions