Go语言利用接口实现链表插入功能详解

Go语言利用接口实现链表插入功能详解

目录

1. 接口定义

1.1 空接口

1.2 实现单一接口

1.3 接口多方法实现

2. 多态

2.1 为不同数据类型的实体提供统一的接口

2.2 多接口的实现

3. 系统接口调用

4. 接口嵌套

5. 类型断言

5.1 断言判断

5.2 多类型判断

6. 使用接口实现链表插入

1. 接口定义

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

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

接口又称为动态数据类型,在进行接口使用的的时候,会将接口对位置的动态类型改为所指向的类型

会将动态值改成所指向类型的结构体

每个接口由数个方法组成,接口的定义格式如下:

其中参数列表和返回值列表中的参数变量名可以省略

type 接口类型名 interface{
    方法名1( 参数列表1 ) 返回值列表1
    方法名2( 参数列表2 ) 返回值列表2
    …
}

自定义接口步骤

① 定义接口

② 定义结构体

③ 接口实现(绑定结构体)

④ 定义接口变量,初始化结构体,调用接口实现功能

1.1 空接口

空接口就相当于一个空指针

package main import "fmt" //定义空接口 type Test interface{} func main() { //声明接口方法1 var t Test fmt.Printf("t的类型: %T, t的值: %v\n", t, t) //声明接口方法2 var a interface{} var b int a = b fmt.Printf("a的类型: %T, a的值: %v\n", a, a) }

输出结果如下

t的类型: <nil>, t的值: <nil>
a的类型: int, a的值: 0

1.2 实现单一接口

结构体使用接口打印信息

package main import "fmt" type Student struct { Name string Age int Score float32 } //接口定义:接口是功能的抽象,不需要实现 type Test interface { Print() } //指针类型实现接口 func (p *Student) Print() { fmt.Printf("name:[%s]\n", p.Name) fmt.Printf("age:[%d]\n", p.Age) fmt.Printf("score:[%f]\n", p.Score) } //值类型实现接口 /* func (p Student) Print() { fmt.Printf("name:[%s]\n", p.Name) fmt.Printf("age:[%d]\n", p.Age) fmt.Printf("score:[%f]\n", p.Score) } */ func main() { //声明接口变量 var t Test //结构体初始化 var stu Student = Student{ Name: "zhangsan", Age: 18, Score: 90, } //把结构体赋值给接口 t = &stu //接口功能 t.Print() }

输出结果如下

name:[zhangsan]
name:[18]
name:[90.000000]

1.3 接口多方法实现 package main import "fmt" type Student struct { Name string Age int Score float32 } //接口定义:接口是功能的抽象,不需要实现 type Test interface { Print() Sleep() } //接口的实现 func (p *Student) Print() { fmt.Printf("name:[%s]\n", p.Name) fmt.Printf("age:[%d]\n", p.Age) fmt.Printf("score:[%f]\n", p.Score) } //接口中包含多个方法,如果要使用此接口就要实现接口中包含的所有方法 func (p *Student) Sleep() { fmt.Println("正在睡眠~") } func main() { //声明接口变量 var t Test //结构体初始化 var stu Student = Student{ Name: "zhangsan", Age: 18, Score: 90, } //把结构体赋值给接口 t = &stu //接口功能 t.Print() t.Sleep() }

输出结果如下

name:[zhangsan]
name:[18]
name:[90.000000]
正在睡眠~

示例,在电脑上定义一个USB接口,实现鼠标、U盘、风扇的功能

package main import "fmt" //定义电脑 type Computer struct { Brand string//品牌 Price float32//价格 } //定义USB接口 type USB interface { mouse() store() fan() } //接口功能实现 func (c Computer) mouse() { fmt.Println("鼠标") } func (c Computer) store() { fmt.Println("U盘") } func (c Computer) fan() { fmt.Println("风扇") } func main() { //初始化结构体 var com Computer //初始化接口 var usb USB com.Brand = "thinkpad" com.Price = 5000 //接口调用 usb = com usb.mouse() usb.fan() usb.store() }

输出结果如下

鼠标
风扇
U盘

2. 多态

对于同一个接口,赋予给不同的结构体,使用相同的方法而产生出不同的操作,称之为多态。

2.1 为不同数据类型的实体提供统一的接口 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 (p *Student) Print() { fmt.Printf("name:[%s]\n", p.Name) fmt.Printf("age:[%d]\n", p.Age) fmt.Printf("Score:[%f]\n", p.Score) } //教师结构体的实现 func (p *Teacher) Print() { fmt.Printf("name:[%s]\n", p.Name) fmt.Printf("age:[%d]\n", p.Age) fmt.Printf("Class:[%d]\n", p.Class) } //接口中包含多个方法,如果要使用此接口就要实现接口中包含的所有方法 func (p *Student) Sleep() { fmt.Println("正在睡眠~") } func (p *Teacher) Sleep() { fmt.Println("正在休息~") } func main() { //声明接口变量 var t Test //学生初始化 var stu Student stu.Name = "zhangsan" stu.Age = 18 stu.Score = 90 //教师初始化 var tea Teacher tea.Name = "lisi" tea.Age = 25 tea.Class = 3 //学生接口功能调用实现 t = &stu t.Print() t.Sleep() fmt.Println("----------------------------") //教师接口功能调用实现 t = &tea t.Print() t.Sleep() }

输出结果如下

name:[zhangsan]
age:[18]
Score:[90.000000]
正在睡眠~
----------------------------
name:[lisi]
age:[25]
Class:[3]
正在休息~

2.2 多接口的实现 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: 18, Score: 90, } //调用接口实现功能 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) } } 4. 接口嵌套

示例:

文件读写测试

package main import "fmt" //读取的接口 type Reader interface { Read() } //写入的接口 type Writer interface { Writer() } //接口的嵌套 type ReadWriter interface { Reader Writer } //文件结构体 type File struct{} //实现Reader接口 func (f *File) Read() { fmt.Println("文件读取") } //实现Writer接口 func (f *File) Writer() { fmt.Println("文件写入") } //定义读写操作函数 func Test(rw ReadWriter) { //rw为接口变量 rw.Read()//使用读写的方法 rw.Writer() } func main() { var f File//定义结构体,初始化文件 Test(&f) }

输出结果如下

文件读取
文件写入

5. 类型断言

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

示例

package main import "fmt" func main() { //定义空接口 var a interface{} var b int a = b //a为int类型 //断言赋值 fmt.Printf("a= %v, 类型: %T\n", a, a) c := a.(int) fmt.Printf("c= %v, 类型: %T\n", c, c) }

输出结果如下

a= 0, 类型: int
c= 0, 类型: int

5.1 断言判断 package main import "fmt" func main() { //定义空接口 var a interface{} var b string a = b //a为int类型 //断言赋值 fmt.Printf("a= %v, 类型: %T\n", a, a) c, err := a.(int) if err { fmt.Printf("c= %v, 类型: %T\n", c, c) } else { fmt.Println("不是int类型") } }

输出结果如下

a= , 类型: string
不是int类型

package main import "fmt" func Test(t interface{}) { //转换类型判断 v, err := t.(int) if !err { fmt.Println("type is not int") return } v++ fmt.Println(v) } func main() { a := "张三" Test(a) }

输出结果如下

type is not int

5.2 多类型判断 package main import "fmt" func classifier(items ...interface{}) { //遍历复杂集合 for i, v := range items { //变量.(type)职能作用在switch语句中,专门用于判断类型 switch v.(type) { case bool: fmt.Printf("第 %d 个数据类型是 bool\n", i) case int, 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("张三", 3.14, true, 80, nil) }

输出结果如下

第 0 个数据类型是 string
第 1 个数据类型是 float
第 2 个数据类型是 bool
第 3 个数据类型是 int
第 4 个数据类型是其他类型

6. 使用接口实现链表插入 package main import "fmt" //节点结构体 type LinkNode struct { data interface{} next *LinkNode } //链表结构体 type Link struct { head *LinkNode tail *LinkNode } //从头部插入 func (p *Link) InsertHead(data interface{}) { node := &LinkNode{ data: data, next: nil, } //判断是否为空链表 if p.head == nil && p.tail == nil { p.head = node p.tail = node return } //当前节点的next是原头部节点 node.next = p.head //更新头部 p.head = node } //从尾部插入 func (p *Link) InsertTail(data interface{}) { node := &LinkNode{ data: data, next: nil, } //判断是否为空链表 if p.head == nil && p.tail == nil { p.head = node p.tail = node return } //原尾部节点的next是当前节点 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 intLink Link for i := 0; i < 10; i++ { //intLink.InsertHead(i) intLink.InsertTail(i) } intLink.Req() }

输出结果如下

&{0 0xc000096078}
&{1 0xc000096090}
&{2 0xc0000960a8}
&{3 0xc0000960c0}
&{4 0xc0000960d8}
&{5 0xc0000960f0}
&{6 0xc000096108}
&{7 0xc000096120}
&{8 0xc000096138}
&{9 <nil>}

到此这篇关于Go语言利用接口实现链表插入功能详解的文章就介绍到这了,更多相关Go语言接口内容请搜索易知道(ezd.cc)以前的文章或继续浏览下面的相关文章希望大家以后多多支持易知道(ezd.cc)!

推荐阅读

    公共CPU接口类型的详细描述

    公共CPU接口类型的详细描述,,我们知道CPU是电脑的大脑, CPU的处理速度直接决定电脑的性能, 那你知道CPU发展到现在, 都那些CPU接口类型吗.

    FM1和AM3接口将在今年年底前淘汰

    FM1和AM3接口将在今年年底前淘汰,,据来自主板制造商的消息,AMD将开始逐步淘汰Socket FM1和Socket AM3接口从本月开始的处理器,最后消失在第

    主板类型百科全书(基于芯片分类)

    主板类型百科全书(基于芯片分类),,电脑维修基础之主板型号熟悉,主板芯片型号区分,涵盖nVIDIA系列intel系列AMD系列主板型号,主板型号大全内容较

    Windows8开发版系统高清系统接口图

    Windows8开发版系统高清系统接口图,,今天,微软发布,目前由开发者体验版Windows 8操作系统为整个英文系统,Windows 8带来了一系列新功能,没有折

    探探语言设置|探探怎么设置语言

    探探语言设置|探探怎么设置语言,,1. 探探怎么设置语言打开探探软件,然后就有消息提示的红点,点开就行了!其实这些软件都是挺简单的操作的,都是

    git设置编码|git语言设置

    git设置编码|git语言设置,,git设置编码点击cap4j搜索从git直接链接上拉代码。git语言设置Git是一个开源的分布式版本控制系统,可以有效、高

    「显卡上的接口」显卡上的接口有几种

    「显卡上的接口」显卡上的接口有几种,显卡上的接口,本篇文章给大家谈谈显卡上的接口,以及显卡上的接口有几种对应的知识点,希望对各位有所帮

    支持DDR3!AM3接口790gx主板的评价

    支持DDR3!AM3接口790gx主板的评价,,二月,在主板市场,各种各样的AM3主板将推出。对Phenom II处理器的刺激下,每一个主板制造商不能忽视这样一个