1

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.

2
  • Go doesn't have inheritance, so approaching a problem in this manner is usually the wrong choice. Also, the reason you can't do this is that there are no generics, and go types are invariant. Commented Nov 20, 2015 at 21:18
  • Use interfaces. can't find it right now,but there are multiple duplicates of this topic. Commented Nov 20, 2015 at 21:19

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Well, Vehicle can be a type. But he also needs an interface with methods that all vehicles can do, like start, move, shutdown, etc... That would allow him to embed Vehicle in his other types and store them together in an array of types that implement IVehicle or whatever, right?
@saarrrr yeah, sorry if that was unclear. I used IVehicle in the second paragraph because that would be the sensible choice assuming he keeps the Vehicle type. In the last paragraph I'm talking about his current implementation and just trying to give some broader conceptual information about embedding. The "is a", "has a" crap is the way I remember academics explaining it ;)
That's what I thought, just making sure my own understand wasn't whacked to all hell. Thanks, great answer.
Not sure if in needs a follow up question but how could you ensurer the data structure is correctly encoded as JSON play.golang.org/p/W0luNEuZ40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.