A question about implement array's sort.Interface

158 views
Skip to first unread message

Nan Xiao

unread,
May 25, 2016, 1:38:00 AM5/25/16
to golang-nuts
Hi all,

I want to implement an array which satisfies the sort.Interface, and the following code works as my expectation:

package main
import (
"fmt"
"sort"
)
type command struct  {
name string
}
type byName [4]command
func (a *byName) Len() int           { return len(*a) }
func (a *byName) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a *byName) Less(i, j int) bool { return a[i].name < a[j].name }
func main() {
c := byName([...]command{
{"breakpoint"},
{"help"},
{"args"},
{"continue"},
})
fmt.Println("Before sorting: ", c)
sort.Sort(&c)
fmt.Println("After sorting: ", c)
}

Now, I change the main function:
func main() {
c := [...]command{
{"breakpoint"},
{"help"},
{"args"},
{"continue"},
}
fmt.Println("Before sorting: ", c)
sort.Sort(&(byName(c)))
fmt.Println("After sorting: ", c)
Then the compiler complains:
src\Hello.go:26: cannot take the address of byName(c) 

So except convert "[4]command" to "byName" in the declaration:
c := byName([...]command{
{"breakpoint"},
{"help"},
{"args"},
{"continue"},
})
Is there any method to achieve the same goal?

Thanks in advance!

Best Regards
Nan Xiao  

Dave Cheney

unread,
May 25, 2016, 1:48:36 AM5/25/16
to golang-nuts
Why not use a slice rather than an array ?

Frits van Bommel

unread,
May 25, 2016, 1:51:40 AM5/25/16
to golang-nuts
sort.Interface is more commonly defined on slice types than on arrays.

// ...
type byName []command
func (a byName) Len() int           { return len(a) }
func (a byName) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a byName) Less(i, j int) bool { return a[i].name < a[j].name }
func main() {
// ...

fmt.Println("Before sorting: ", c)
sort.Sort(byName(c[:]))

fmt.Println("After sorting: ", c)
}

(untested, but it should work)
Note that because you only change the contents, not the len() and cap(), you can pass by value and still have it work, so no issues with address-taking.

Nan Xiao

unread,
May 25, 2016, 2:01:39 AM5/25/16
to Frits van Bommel, golang-nuts
Hi Dave,

I find many tutorials are using slice as an example, so just want to try another flavor.

Best Regards
Nan Xiao

--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/SI5s9JlQBp8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Val

unread,
May 25, 2016, 9:54:11 AM5/25/16
to golang-nuts, fvbo...@gmail.com
Hello Xiao

It is totally legit to use sort.Sort on an array type.  The sort package has no idea whether the backing structure is slice, or array, or real goods wagons, it just needs to have Len/Swap/Less to play with.

For some reason, you can take the address of a variable, but not of a func result or conversion result :

https://play.golang.org/p/FpVPfOkyX7
https://play.golang.org/p/70lMhVQ-U-
https://play.golang.org/p/Mpg4Chg8Nj
https://play.golang.org/p/cOoaQve5Zh
https://play.golang.org/p/FgI_b3GyTJ

Here is a spec section about what you may take address of. It is related to the concept of "addressability".  There also exist some old discussions on golang-nuts and on stackoverflow about "why can't I taka address of func call" or similar.

Cheers
 Val

luz...@gmail.com

unread,
May 25, 2016, 12:27:31 PM5/25/16
to golang-nuts, fvbo...@gmail.com
On Wednesday, May 25, 2016 at 3:54:11 PM UTC+2, Val wrote:
The sort package has no idea whether the backing structure is slice, or array, or real goods wagons

It can even sort a uint32: https://play.golang.org/p/0em00MxRJz  (code by @davecheney)
Reply all
Reply to author
Forward
0 new messages