I have two structs (Dimension and Metric) and part of their attributes overlap, so I decided to go with a common struct that is then encapsulated.
type Attribute struct {
Function *string
Id *string
}
type Dimension struct {
Attribute
Class *string
}
type Metric struct {
Alias *string
Attribute
}
What I would like is to have a function that takes a slice of either Dimensions or a slice of Metrics and sorts it by the id
field, which is common between the two.
dimensions := []Dimension{...}
metrics := []Metric{...}
sortById(dimensions)
sortById(metrics)
I could use a slice of interface types func sortItems(items []interface{})
but I would prefer to avoid this so I was wondering how I can do something like the lines below.
func sortItems(items []Attribute) {
//Sort here
}
If I try this, I am getting cannot use metrics (type []Metric) as type []Attribute in argument to this.sortItems
which is to be expected, but I am new enough to Go not to know how to approach this.
I know I could just create two functions (one for each type) but I am curious what the correct pattern is for tackling issues like these in Go.
Define an interface and have it be implemented by the common type Attribute
.
Something like this:
type Attributer interface {
GetId() *int
}
func (a Attribute) GetId() *int {
return a.Id
}
func sortItems(items []Attributer) {
//Sort here
}
By virtue of embedding the Attribute
type, both Dimension
and Metric
can be used wherever the Attributer
interface is expected.
So this will compile just fine.
items := []Attributer{Dimension{}, Metric{}}