Golang interface你想了解的这里都有!

Golang interface 

在了解类型断言之前我们需要新了解一下interface,所以interface算是下一个博客内容的铺垫。

什么是interface,它都有什么用处?

1.interface type

就是一组方法签名的集合。我们使用一个接口来识别一个对象能够进行的操作。这也是我们最常用的方式,不管是在golang这门语言还是其他OOP类型的语言,碰到一个interface我们的第一想法是,它包含什么操作(方法)?谁实现了它?怎么实现它?

2.interface values

接口也是一种类型,那么这个接口类型的值到底是什么?一个interface可以存储任何实现了该接口的类型(里氏替换原则)。

3.The case of the empty interface

空接口类型 interface{}一个方法签名也不包含,所以所有的数据类型都实现了该方法,空接口类型interface{}在描述一个对象实例的行为上力不从心,但是当我们需要存储任意数据类型的实例的时候,空接口类型的使用当作java或者C#的object类型来使用。

func main() {
	var msg interface{}
	s := "Hello"
	msg = s
	fmt.Println(msg)
}
  • 如果一个函数的参数包括空接口类型interface{},那么它可以接收任何类型
  • 如果一个函数返回了一个空接口类型interface{},那么它可以返回任意类型

4.Functions with interface parameters 

举例来说,我们已经知道fmt.Print 是一个可变参数的函数,他可以接受任意数量的参数。

我们来查看一下fmt.Print可接受任意数量参数的写法:

func main() {
	Test("a", "b", "c", "d", "e")
}

func Test(a ...interface{}) {
	for _, arg := range a {
		fmt.Print(arg)
	}
}

详细可以查看   fmt.Println()  是如何实现的。

这里我们顺藤摸瓜可以看到fmt包里居然有下面这个接口:

type Stringer interface {
     String() string
}

那我们就尝试着去实现这个interface看一看,不出所料的我们并没有写这个inteface但是却显示实现了某个接口:

测试代码:

func main() {
	a := new(A)
	fmt.Println(a)
}

type A struct {
}

func (a *A) String() string {
	return "可以看看实现的效果!"
}

输出:

可以看看实现的效果!

果然fmt.pringt()输出使用的是struct的tostring()方法,可以看出在标准库中还是有不少使用此类方式来实现的。

例如:sort包

func main() {
	list := []int {10, 9, 8, 7, 6, 5, 4, 3, 2,1}
	fmt.Println("The list is: ", list)
	sort.Ints(list)
	fmt.Println("The sorted list is: ", list)
}

输出:

The list is:  [10 9 8 7 6 5 4 3 2 1]
The sorted list is:  [1 2 3 4 5 6 7 8 9 10]

 我们进入sort包内查看一下。发现如下interface

// A type, typically a collection, that satisfies sort.Interface can be
// sorted by the routines in this package. The methods require that the
// elements of the collection be enumerated by an integer index.
type Interface interface {
	// Len is the number of elements in the collection.
	Len() int
	// Less reports whether the element with
	// index i should sort before the element with index j.
	Less(i, j int) bool
	// Swap swaps the elements with indexes i and j.
	Swap(i, j int)
}

实现上述接口就可以实现使用Sort进行排序,那么我们尝试一下:

package main

import (
	"fmt"
	"sort"
	"strconv"
)

func main() {
	TestSortMyStruct()
}

func TestSortMyStruct()  {
	group := PersonGroup{
		Person{name: "zhangsan", age:24},
		Person{name: "lisi", age:23},
		Person{name: "wangwu", age:104},
		Person{name: "tiezhu", age:44},
		Person{name: "gangdan", age:34},
		Person{name: "xiaoqiang", age:54},
		Person{name: "xiaozhang", age:74},
		Person{name: "xiaodong", age:4},
	}
    fmt.Println("未排序")
	for _, v := range group{
		fmt.Println(v)
	}

	sort.Sort(group)
	fmt.Println("排序后")
	for _, v := range group{
		fmt.Println(v)
	}
}
//实现了ToString()接口
type Person struct {
	name string
	age int
	phone string
}

func (p Person) String() string {
	return "(name: " + p.name + " - age: "+strconv.Itoa(p.age)+ " years)"
}

//实现了Sort接口
type PersonGroup []Person

func (g PersonGroup) Len() int {
	return len(g)
}

func (g PersonGroup) Less(i, j int) bool {
	if g[i].age < g[j].age {
		return true
	}
	return false
}

func (g PersonGroup) Swap(i, j int){
	g[i], g[j] = g[j], g[i]
}

 输出:

未排序
(name: zhangsan - age: 24 years)
(name: lisi - age: 23 years)
(name: wangwu - age: 104 years)
(name: tiezhu - age: 44 years)
(name: gangdan - age: 34 years)
(name: xiaoqiang - age: 54 years)
(name: xiaozhang - age: 74 years)
(name: xiaodong - age: 4 years)
排序后
(name: xiaodong - age: 4 years)
(name: lisi - age: 23 years)
(name: zhangsan - age: 24 years)
(name: gangdan - age: 34 years)
(name: tiezhu - age: 44 years)
(name: xiaoqiang - age: 54 years)
(name: xiaozhang - age: 74 years)
(name: wangwu - age: 104 years)

可以看到实现了Sort接口我们就可以去使用sort进行排序。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值