Let us say that we have a fairly complicated struct
with numerous fields, that I need to sort in several places according to different criteria, e.g.
type MySuperType struct {
x0, x1, x2, x3 xType
// possibly even more fields
}
// sort 1: ascending x0, then descending x1, then more stuff
// sort 2: if x4==0 then applyCriteria2a else applyCriteria2b
func f1(mySuperSlice []MySuperType) {
// sort 'myList' according sort #1
// do something with the sorted list
}
func f2(mySuperSlice []MySuperType) {
// sort 'myList' according sort #2
// do something with the sorted list
}
func f3(mySuperSlice []MySuperType) {
// sort 'myList' according sort #1, note: we use sort #1 again!
// do something with the sorted list
}
Proposed solution 1:
Create a new type (alias of []MySuperType
) that implements sort.Interface
for each sorting criteria required.
Problems:
(i) there is some duplicated code, as the functions Len
and Swap
are going to be identical
(ii) there is going to be a bunch of new types lying around that do not help with the overall readability of the program --- these new types don't really represent anything, plus the only thing that really matters is the Less
function.
Proposed solution 2:
Use sort.Slice
It would be the perfect solution (see this answer), but from my understanding, the sorting function has to be specified inline (I get an error invalid receiver type []T ([]T is an unnamed type)
when I tried to define it elsewhere, which means that I need to define an alias for []T
and we are back to solution 1).
Now, the problem with defining the function inline is that (i) given the complexity of MySuperType
, the function can be very long and (ii) the functions are going to be duplicated in several place (e.g. in f1
and f3
in my example above) -- much more annoying that in solution 1 as the sorting functions can be long and complex.
Note: (i) would not be that much of an issue if we did not have (ii) actually
Question:
Given my current understanding and knowledge of Go, I would use solution 1.
But does anyone knows a different approach that elegantly solves this problem or suggestions to improve the drawbacks listed above?