【golang】代码学习
package main import ( "fmt" "sort" ) // A couple of type definitions to make the units clear. type earthMass float64 type au float64 // A Planet defines the properties of a solar system object. type Planet struct { name string mass earthMass distance au } // By is the type of a "less" function that defines the ordering of its Planet arguments. type By func(p1, p2 *Planet) bool // Sort is a method on the function type, By, that sorts the argument slice according to the function. func (by By) Sort(planets []Planet) { ps := &planetSorter{ planets: planets, by: by, // The Sort method's receiver is the function (closure) that defines the sort order. } sort.Sort(ps) } // planetSorter joins a By function and a slice of Planets to be sorted. type planetSorter struct { planets []Planet by func(p1, p2 *Planet) bool // Closure used in the Less method. } // Len is part of sort.Interface. func (s *planetSorter) Len() int { return len(s.planets) } // Swap is part of sort.Interface. func (s *planetSorter) Swap(i, j int) { s.planets[i], s.planets[j] = s.planets[j], s.planets[i] } // Less is part of sort.Interface. It is implemented by calling the "by" closure in the sorter. func (s *planetSorter) Less(i, j int) bool { return s.by(&s.planets[i], &s.planets[j]) } var planets = []Planet{ {"Mercury", 0.055, 0.4}, {"Venus", 0.815, 0.7}, {"Earth", 1.0, 1.0}, {"Mars", 0.107, 1.5}, } // ExampleSortKeys demonstrates a technique for sorting a struct type using programmable sort criteria. func main() { // Closures that order the Planet structure. name := func(p1, p2 *Planet) bool { return p1.name < p2.name } mass := func(p1, p2 *Planet) bool { return p1.mass < p2.mass } distance := func(p1, p2 *Planet) bool { return p1.distance < p2.distance } decreasingDistance := func(p1, p2 *Planet) bool { return distance(p2, p1) } // Sort the planets by the various criteria. By(name).Sort(planets) fmt.Println("By name:", planets) By(mass).Sort(planets) fmt.Println("By mass:", planets) By(distance).Sort(planets) fmt.Println("By distance:", planets) By(decreasingDistance).Sort(planets) fmt.Println("By decreasing distance:", planets) }
这段代码的功能无所谓,这段代码揭示了如何巧妙地设计几个排序函数,让它和系统的sort函数结合起来使用。
1,理解sort.Sort()
首先,sort.Sort(sortFunc),这里使用了interface{},只需要sortFunc来定义自己的实现;
sortFunc,需要定义Len, Swap, Less这三个函数
其中,Swap这个函数可以复用,Len这个函数也可以复用,但是Less这个函数需要自定义
不同的sortFunc,对应不同的Less。
1.1,理解sort.Less
其次,Less函数定义,不同的Less函数,对应不同的功能;
nameLess, massLess, distanceLes, decreasingDistanceLess,这表示是四个不同的Less函数;
2,理解planetSorter
planetSorter相当于一个包装类,包装了两个参数:a,planets=数据本身;b,by=Less的封装;
planets好理解,是数据,只需要赋值进去就好了;
by不太好理解,by是个结构体的一部分,不同于int, float, string, []string等数据结构,它是个func;
有名函数完成定义之后(mass,name等都是有名函数),这些有名函数赋值给planetSorter.by,就可以使用了。
其实也可以这么用:
nameLess := name
func createSorter(planets []planet, sortLessFunc func(p1, p2 *planet) bool) *planetSorter { return &planetSorter{planets: planets, by: sortLessFunc} } sort.Sort(createSorter(planets, nameLess)) // 这就完成了排序的功能,使用的nameLess的排序,对planets数据进行排序
这样处理起来更简单,理解起来更方便;
我们来理解下官方的代码:
By(lessFunc).Sort(planets) // 关键语句
type By struct/func = class LessFuncType{}
拆分1: By 约等于类的初始化
By(lessFunc) = new LessFuncType(lessFunc) // 类似于new INT(1) (INT是int的type,使用1初始化INT类型)
拆分2: Sort函数约等于调用类的成员函数
By(lessFunc).Sort(planets) = (class LessFuncType).Sort(planets) // 调用对象的成员函数的意思,实际并不需要一定借助By来实现,只是这么实现代码量少,能利用go的一些特性
我们用createSorter也是可以做的,而且没有理解负担,挺好的;
最后
我们倾向于用我们自己的理解和实现来实现代码,而不是当前语言支持的那种方式来实现,也是ok的;并没有什么偏向;
跟 章亦春 说的一样,看ssl代码还是nginx代码来着,有很多汇编语言的风格,实际可以用C来实现也是OK的,这就是语言风格倾向的问题,没有严格的对错;
只要是实现了,就是ok的;