Go语言-接口

目录

前言

1、接口的定义

2、多态

3、系统接口调用

4、接口嵌套

5、类型断言

6、链表使用


前言

接口不需要显示的实现,只需要一个变量,含有接口类型的所有方法,那么这个变量就实现了这个接口,如果一个变量含有多个interface类型的方法,那么这个变量就实现了多个接口。

1、接口的定义

概念:Interface类型可以定义一组的方法,不需要实现,并且不能包含任何变量,称之为接口。

语法格式:

type example interface {
    Method1(参数列表)返回值列表
    Method2(参数列表)返回值列表
    ...
}

示例:空接口使用。

package main

import "fmt"

//定义接口,不传入任何方法,表示为空接口(空指针)。
type Test interface{}

func main() {
	var a Test
	fmt.Printf("a的类型:%T,a的值:%v\n", a, a)
	//另一种方式定义接口
	var b interface{}
	//接口为空时,赋给接口什么类型,接口就会变成什么类型
	var c int
	b = c
	fmt.Printf("b的类型:%T,b的值:%v", b, b)
}

//运行结果为:
a的类型:<nil>,a的值:<nil>
b的类型:int,b的值:0

示例:结构体使用接口打印信息。

package main

import "fmt"

//定义结构体
type Student struct {
	Name  string
	Age   int
	Score float32
}

//定义接口
type Test interface {
	Print()
	Sleep()
}

//接口实现
func (s Student) Print() {
	fmt.Printf("name:[%s]\n", s.Name)
	fmt.Printf("age:[%d]\n", s.Age)
	fmt.Printf("score:[%f]\n", s.Score)
}
func (s Student) Sleep() {
	fmt.Println("正在睡觉。。。")
}
func main() {
	//声明接口变量
	var t Test
	//结构体初始化
	var stu Student = Student{
		Name:  "zhangsan",
		Age:   19,
		Score: 70,
	}
	//结构体赋值接口
	t = stu
	//接口功能
	t.Print()
	t.Sleep()
}

//运行结果为:
name:[zhangsan]
age:[19]
score:[70.000000]
正在睡觉。。。

2、多态

示例:为不同数据类型的实体提供统一的接口。

package main

import "fmt"

//定义结构体
type Persion struct {
	Name string
	Age  int
}
type Student struct {
	Persion
	Score float32
}
type Teacher struct {
	Persion
	Class int
}

//定义接口
type Test interface {
	Print()
	Sleep()
}

//学生接口实现
func (s Student) Print() {
	fmt.Printf("name:[%s]\n", s.Name)
	fmt.Printf("age:[%d]\n", s.Age)
	fmt.Printf("score:[%f]\n", s.Score)
}
func (s Student) Sleep() {
	fmt.Println("正在睡觉。。。")
}

//教师接口实现
func (t Teacher) Print() {
	fmt.Printf("name:[%s]\n", t.Name)
	fmt.Printf("age:[%d]\n", t.Age)
	fmt.Printf("score:[%d]\n", t.Class)
}
func (s Teacher) Sleep() {
	fmt.Println("正在休息。。。")
}
func main() {
	//声明接口变量
	var t Test
	//学生初始化
	var stu Student
	stu.Name = "zhangsan"
	stu.Age = 20
	stu.Score = 80
	//教师初始化
	var tea Teacher
	tea.Name = "lisi"
	tea.Age = 40
	tea.Class = 13

	//学生接口功能使用
	t = stu
	t.Print()
	t.Sleep()
	fmt.Println("-------------------")
	//教师接口功能使用
	t = tea
	t.Print()
	t.Sleep()
}

//运行结果为:
name:[zhangsan]
age:[20]
score:[80.000000]
正在睡觉。。。
-------------------
name:[lisi]
age:[40]
score:[13]
正在休息。。。

示例:多接口实现。

package main

import "fmt"

//多接口实现
//接口1
type Test1 interface {
	Print()
}

//接口2
type Test2 interface {
	Sleep()
}

//结构体
type Student struct {
	Name  string
	Age   int
	Score float32
}

//接口1实现
func (s Student) Print() {
	fmt.Printf("name:%s\n", s.Name)
}

//接口2实现
func (s Student) Sleep() {
	fmt.Println("正在睡觉。。。")
}

func main() {
	//接口1
	var t1 Test1
	//接口2
	var t2 Test2
	//初始化结构体
	var stu Student = Student{
		Name:  "zhangsan",
		Age:   20,
		Score: 80,
	}
	//调用接口实现功能
	t1 = stu
	t1.Print()
	t2 = stu
	t2.Sleep()
}

//运行结果为:
name:zhangsan
正在睡觉。。。

3、系统接口调用

示例:使用接口进行排序。

package main

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

//结构体
type Student struct {
    Name  string
    Age   int
    Score float32
}

//切片
type StudentArray []Student

//go语言提供了sort 接口。使用接口里的方法即可
//实现sort接口
func (sa StudentArray) Len() int {
    return len(sa)
} //获取切片长度
func (sa StudentArray) Less(i, j int) bool {
    return sa[i].Name > sa[j].Name
} //两数比大小
func (sa StudentArray) Swap(i, j int) {
    sa[i], sa[j] = sa[j], sa[i]
} //两数交换

func main() {
    //Student 切片
    var stus StudentArray

    //生成10个结构体,放入切片中
    for i := 0; i < 10; i++ {
        var stu Student = Student{
            Name:  fmt.Sprintf("stu%d", rand.Intn(100)),
            Age:   rand.Intn(120),
            Score: rand.Float32() * 100,
        }

        //结构体元素存入到切片中
        stus = append(stus, stu)
    }

    //遍历
    for _, v := range stus {
        fmt.Println(v)
    }

    fmt.Println("--------------------------")
    //排序
    sort.Sort(stus)
    //遍历
    for _, v := range stus {
        fmt.Println(v)
    }
}

//运行结果为:
{stu81 87 66.45601}
{stu59 1 68.682304}
{stu25 20 9.696952}
{stu0 14 81.36399}
{stu62 89 31.805817}
{stu74 51 29.310184}
{stu37 26 20.318687}
{stu66 8 86.249146}
{stu47 67 75.2573}
{stu88 30 69.67192}
--------------------------
{stu88 30 69.67192}
{stu81 87 66.45601}
{stu74 51 29.310184}
{stu66 8 86.249146}
{stu62 89 31.805817}
{stu59 1 68.682304}
{stu47 67 75.2573}
{stu37 26 20.318687}
{stu25 20 9.696952}
{stu0 14 81.36399}

4、接口嵌套

示例:文件读写测试。

package main

import "fmt"

//接口嵌套
//Reader读接口
type Reader interface {
	read()
}

//Writer写接口
type Writer interface {
	write()
}

//嵌套读写接口
type ReadWriter interface {
	Reader
	Writer
}

//结构体
type File struct{}

//接口实现
func (f *File) read() {
	fmt.Println("文件被读取")
}
func (f *File) write() {
	fmt.Println("文件被写入")
}

//读写操作函数
func Test(rw ReadWriter) {
	rw.read()
	rw.write()
}

func main() {
	//初始化文件
	var f File
	Test(&f)
}

//运行结果为:
文件被读取
文件被写入

5、类型断言

因为接口是一般类型,需要明确具体类型的时候就需要使用类型断言。 

示例:

package main

import "fmt"

//类型断言
func main() {
	//定义接口
	var a interface{}
	var b int
	a = b
	fmt.Printf("a的类型:%T,a的结构:%v\n", a, a)
	//类型判断处理
	c, err := a.(int)
	if err == true {
		fmt.Printf("c的类型:%T,c的结构:%v\n", c, c)
	} else {
		fmt.Println("不属于int类型")
	}
}

//运行结果为:
a的类型:int,a的结构:0
c的类型:int,c的结构:0

示例:断言判断。

package main

import (
	"fmt"
)

//多数据类型判断处理
func classifier(items ...interface{}) {
	//遍历复杂集合
	for i, v := range items {
		//switch...type结合类型判断
		switch v.(type) {
		case bool:
			fmt.Printf("第%d个数据类型是bool\n", i)
		case int, int8, int16, int32, int64:
			fmt.Printf("第%d个数据类型是int\n", i)
		case float32, float64:
			fmt.Printf("第%d个数据类型是float\n", i)
		case string:
			fmt.Printf("第%d个数据类型是string\n", i)
		default:
			fmt.Printf("第%d个数据类型是其他类型\n", i)
		}
	}
}
func main() {
	classifier("zhangsan", 18, 21.23, false, nil)
}

//运行结果为:
第0个数据类型是string
第1个数据类型是int
第2个数据类型是float
第3个数据类型是bool
第4个数据类型是其他类型

6、链表使用

示例:

package main

import "fmt"

//使用接口实现链表插入
//节点结构体
type LinkNode struct {
	data interface{}
	next *LinkNode
}

//链表结构体
type Link struct {
	head *LinkNode
	tail *LinkNode
}

//头部插入
func (p *Link) insertHead(m interface{}) {
	var node *LinkNode = &LinkNode{
		data: m,
		next: nil,
	}
	if p.head == nil && p.tail == nil {
		p.head = node
		p.tail = node
		return
	}
	//节点平移
	node.next = p.head
	p.head = node
}

//尾部插入
func (p *Link) insertTail(m interface{}) {
	var node *LinkNode = &LinkNode{
		data: m,
		next: nil,
	}
	if p.head == nil && p.tail == nil {
		p.head = node
		p.tail = node
		return
	}
	//节点平移
	p.tail.next = node
	p.tail = node
}

//遍历
func (p *Link) Req() {
	lp := p.head
	for lp != nil {
		fmt.Println(lp)
		lp = lp.next
	}
}

func main() {
	var link Link
	//节点插入
	for i := 0; i < 10; i++ {
		//link.insertHead(i)
		link.insertTail(i)
	}
	//遍历
	link.Req()
}

//运行结果为:
&{0 0xc000096078}
&{1 0xc000096090}
&{2 0xc0000960a8}
&{3 0xc0000960c0}
&{4 0xc0000960d8}
&{5 0xc0000960f0}
&{6 0xc000096108}
&{7 0xc000096120}
&{8 0xc000096138}
&{9 <nil>}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值