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>}