Ah, this is interesting: sort.Sort()
expects the type to define an ordering and some array operations. You can have "X-sortable point list" and "Y-sortable point list" types, but making them share the array ops works differently from in other languages because Go doesn't use inheritance.
The first way I thought of is to create XSortablePoints
and YSortablePoints
types that each independently implement sort.Interface
, and convert your Points
instance to whichever one you need at the moment--see here: http://play.golang.org/p/9V3WlKjOwX.
Then nemo had a better way: type embedding allows XSortablePoints
and YSortablePoints
to share the functions for array operations. Also, nemo doesn't save the sortable types in a variable, which makes sense as they only exist for this one sort call. Here's adjusted sample code: http://play.golang.org/p/wNm-ilM18n
Note that neither of these approaches actually copies your point data when you cast, just the slice header. You can see that by looking at the pointer addresses printed out by the first example.
You can get fancier: there's a Points.Sort taking an arbitrary comparison function at http://play.golang.org/p/4PmJVi2_7D. I think the brute-force approach of just defining more types is fine as long as you only have two or three orderings, but situations vary. Note that for types much bigger than the points here, you might want to define the comparer to take pointers rather than values, to avoid copying.
re: SORT_BY_X
: I'd generally avoid global mode-setting variables that you update as the program runs, because there are lots of ways those can come back to bite you. For example, maybe you'll have two parallel goroutines someday and then trouble happens when they both access the global at once. Or maybe some code will work when the initial value of SORT_BY_X is false
, then someday fail because it was left true
after another task ran. If you do find yourself needing a mode variable, figure out if, instead of it being global, you could make it a function parameter or attach it to an object.
Finally, there might be a package that already provides some of the higher-level functionality you want. For example, there are some packages related to geographic data listed here: https://code.google.com/p/go-wiki/wiki/Projects#GIS