Golang 接口(interface)最佳实践

引用类型:指针、slice切片、map、管道chan、interface等都是引用类型,在作为函数参数的时候进行修改会影响到原有的数据。

实现对Hero结构体切片的排序:sort.Sort(data Interface)

Interface里面有三个方法可以实现,其实也就是你想调用系统提供的方法,对结构体切片进行排序,那么就需要实现接口的三个方法。

其实就是在sort函数里面会使用到接口里面提供的排序方法。(其实就是结构体切片类型实现了那个接口的三个方法,那么就可以去调用sort方法来完成对结构体切片的排序)

结构体的切片类型才能存放多个结构体的变量。

软件包: sort      func Sort(data Interface)

package main

import (
	"fmt"
	"math/rand"
	"sort"
)

// Hero 声明hero结构体
type Hero struct {
	Name string
	Age  int
}

// HeroSlice 声明hero结构体切片类型
type HeroSlice []Hero

// Len 实现Interface接口,将下面的三个方法都实现了。那么就可以调用Sort包里面的Sort方法了
func (hs HeroSlice) Len() int {
	return len(hs)
}

// Less less这个方法就是决定你使用什么标准进行排序
// 按照hero的年龄从小到大排序
func (hs HeroSlice) Less(i, j int) bool {
	return hs[i].Age < hs[j].Age
}

func (hs HeroSlice) Swap(i, j int) {
	temp := hs[i]
	hs[i] = hs[j]
	hs[j] = temp
}

func main() {
	var heroes HeroSlice
	for i := 0; i < 10; i++ {
		hero := Hero{
			Name: fmt.Sprintf("hero~%d", i),
			Age:  rand.Intn(100),
		}
		heroes = append(heroes, hero)
	}

	for _, v := range heroes {
		fmt.Printf("%v", v)
	}

	//调用sort包里面的sort方法,之所以将切片对应的类型放进去,是因为该类型实现了这三个方法
	sort.Sort(heroes)
	fmt.Printf("\n排序后的结果..............\n")
	for _, v := range heroes {
		fmt.Printf("%v", v)
	}

}

{hero~0 99}{hero~1 81}{hero~2 46}{hero~3 33}{hero~4 10}{hero~5 72}{hero~6 43}{hero~7 20}{hero~8 43}{hero~9 18}
排序后的结果..............
{hero~4 10}{hero~9 18}{hero~7 20}{hero~3 33}{hero~6 43}{hero~8 43}{hero~2 46}{hero~5 72}{hero~1 81}{hero~0 99}

如果不想对年龄进行排序了,想对姓名进行排序,修改如下:

func (hs HeroSlice) Less(i, j int) bool {
	return hs[i].Name < hs[j].Name
}

接口的妙用在于实现了上面的方法,那么其余的事情就交给Sort包里面的Sort方法去做,至于里面如何去调用这三个方法的,就不需要你去管了。

其实就是这种方式帮你开放了接口,你将接口实现了,那么排序就自动点将字段完成。最后修改一下赋值的语句,这样更加简洁。

func (hs HeroSlice) Swap(i, j int) {
	hs[i], hs[j] = hs[j], hs[i]
}

上面这种方式就有利于我们实现高质量的代码,开放一些接口让别让去使用,同时将最核心的代码交给最核心的人去写。

将放开的部分开放给别让使用,提供接口。 下面这些方法放开之后就知道按照什么标准排序。能够放开点就放开,不能够放开的就放到内部去。

猜你喜欢

转载自blog.csdn.net/qq_34556414/article/details/133803514
今日推荐