1 // Copyright 2013 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
12 // A couple of type definitions to make the units clear.
13 type earthMass
float64
16 // A Planet defines the properties of a solar system object.
23 // By is the type of a "less" function that defines the ordering of its Planet arguments.
24 type By
func(p1
, p2
*Planet
) bool
26 // Sort is a method on the function type, By, that sorts the argument slice according to the function.
27 func (by By
) Sort(planets
[]Planet
) {
30 by
: by
, // The Sort method's receiver is the function (closure) that defines the sort order.
35 // planetSorter joins a By function and a slice of Planets to be sorted.
36 type planetSorter
struct {
38 by
func(p1
, p2
*Planet
) bool // Closure used in the Less method.
41 // Len is part of sort.Interface.
42 func (s
*planetSorter
) Len() int {
46 // Swap is part of sort.Interface.
47 func (s
*planetSorter
) Swap(i
, j
int) {
48 s
.planets
[i
], s
.planets
[j
] = s
.planets
[j
], s
.planets
[i
]
51 // Less is part of sort.Interface. It is implemented by calling the "by" closure in the sorter.
52 func (s
*planetSorter
) Less(i
, j
int) bool {
53 return s
.by(&s
.planets
[i
], &s
.planets
[j
])
56 var planets
= []Planet
{
57 {"Mercury", 0.055, 0.4},
58 {"Venus", 0.815, 0.7},
63 // ExampleSortKeys demonstrates a technique for sorting a struct type using programmable sort criteria.
64 func Example_sortKeys() {
65 // Closures that order the Planet structure.
66 name
:= func(p1
, p2
*Planet
) bool {
67 return p1
.name
< p2
.name
69 mass
:= func(p1
, p2
*Planet
) bool {
70 return p1
.mass
< p2
.mass
72 distance
:= func(p1
, p2
*Planet
) bool {
73 return p1
.distance
< p2
.distance
75 decreasingDistance
:= func(p1
, p2
*Planet
) bool {
76 return distance(p2
, p1
)
79 // Sort the planets by the various criteria.
80 By(name
).Sort(planets
)
81 fmt
.Println("By name:", planets
)
83 By(mass
).Sort(planets
)
84 fmt
.Println("By mass:", planets
)
86 By(distance
).Sort(planets
)
87 fmt
.Println("By distance:", planets
)
89 By(decreasingDistance
).Sort(planets
)
90 fmt
.Println("By decreasing distance:", planets
)
92 // Output: By name: [{Earth 1 1} {Mars 0.107 1.5} {Mercury 0.055 0.4} {Venus 0.815 0.7}]
93 // By mass: [{Mercury 0.055 0.4} {Mars 0.107 1.5} {Venus 0.815 0.7} {Earth 1 1}]
94 // By distance: [{Mercury 0.055 0.4} {Venus 0.815 0.7} {Earth 1 1} {Mars 0.107 1.5}]
95 // By decreasing distance: [{Mars 0.107 1.5} {Earth 1 1} {Venus 0.815 0.7} {Mercury 0.055 0.4}]