教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 go语言学习笔记 — 接口 — 接口与类型相互转换:在接口和类型之间转换

go语言学习笔记 — 接口 — 接口与类型相互转换:在接口和类型之间转换

发布时间:2021-05-26   编辑:jiaochengji.com
教程集为您提供go语言学习笔记 — 接口 — 接口与类型相互转换:在接口和类型之间转换等资源,欢迎您收藏本站,我们将为您提供最新的go语言学习笔记 — 接口 — 接口与类型相互转换:在接口和类型之间转换资源

使用接口断言(type assertion),我们可以把接口转换成另外一个接口,也可以把接口转换成另外的类型。


1. 类型断言的格式

接口断言类似于控制流中的if,但大量类型断言出现时,应使用更高效的类型分支switch特性。

t := i.(T)

i表示接口变量(断言对象),T表示要转换的目标类型(指定类型),t表示转换后的变量(指定类型接口)。此时,如果i没有实现T,这个语句会触发panic。因此,有以下改进写法:

t, ok := i.(T)

如果断言对象是指定的类型,则返回指定类型接口;如果不是指定的类型,断言的第二个参数将返回false。

如果发生接口未实现,go将会把ok置为false,t置为T类型零值;正常实现时,ok为true。这里ok被认为是接口i是否实现类型T的结果。


2. 把接口转换成其他接口

鸟和猪具有不同特性,鸟可以飞,猪不能飞,但两种动物都可以走。如果使用结构体实现鸟和猪,让它们具备各自特性的Fly()和Walk()方法,就能让鸟和猪各自实现了飞行者接口(Flyer)和行走者接口(Walker)。

对保存有鸟或猪实例的空接口类型interface{}变量进行类型断言,如果断言对象是指定的类型,则返回指定类型接口;如果不是指定的类型,断言的第二个参数将返回false。

package main

import (
	"fmt"
	"testing"
)

// 接口定义
type Flyer interface { // 定义飞行动物接口
	Fly()
}

type Walker interface { // 定义行走动物接口
	Walk()
}

// 接口实现
type bird struct{} // 定义飞行类型

func (b *bird) Fly() { // 实现飞行动物飞行接口
	fmt.Println("bird: fly")
}

func (b *bird) Walk() { // 实现飞行动物行走接口
	fmt.Println("bird: walk")
}

// 接口实现
type pig struct{} // 定义行走类型

func (p *pig) Walk() { // 实现行走动物行走接口
	fmt.Println("pig: walk")
}

func main() {
	// 创建动物名到结构体实例的字典
	animals := map[string]interface{}{
		"bird": new(bird), // 创建出的结构体实例
		"pig":  new(pig),
	}

	// 遍历字典
	for name, obj := range animals { // obj为字典的值,是interface{}类型
		f, isFlyer := obj.(Flyer)   // 使用类型断言获得变量f,转换后的类型是Flyer;isFlyer是接口类型转换是否成功的结果
		w, isWalker := obj.(Walker) // 使用类型断言获得变量w,转换后的类型是Walker;isWalker是接口类型转换是否成功的结果

		fmt.Printf("name: %s isFlyer: %v isWalker: %v\n", name, isFlyer, isWalker)

		if isFlyer {
			f.Fly() // 调用接口方法
		}

		if isWalker {
			w.Walk() // 调用接口方法
		}
	}
}

3. 把接口转换成其他类型

在go中,接口和其他类型的自由转换,前提是接口已经实现。

把接口转换为普通的指针类型。例如,把Walker接口转换成*pig类型,

package main

import (
	"fmt"
)

// 接口定义
type Flyer interface { // 定义飞行动物接口
	Fly()
}

type Walker interface { // 定义行走动物接口
	Walk()
}

// 接口实现
type bird struct{} // 定义飞行类型

func (b *bird) Fly() { // 实现飞行动物飞行接口
	fmt.Println("bird: fly")
}

func (b *bird) Walk() { // 实现飞行动物行走接口
	fmt.Println("bird: walk")
}

// 接口实现
type pig struct{} // 定义行走类型

func (p *pig) Walk() { // 实现行走动物行走接口
	fmt.Println("pig: walk")
}

func main() {
	p1 := new(pig)

	var a Walker = p1
	p2 := a.(*pig) // 把Walker接口转换成*pig结构体指针类型

	fmt.Printf("p1=%p p2=%p", p1, p2) // 格式化输出指针类型
}

// p1=0x118efd0 p2=0x118efd0 ,对比发现p1和p2指针是相同的

在上述代码中,如果把Walker类型转换成*bird类型,将会报错:在接口转换时,main.Walker接口内部保存的是*main.pig,而不是*main.bird。因此,在接口转换成其他类型时,接口内保存实例对应的类型指针,必须要转换成相对应的类型指针。


到此这篇关于“go语言学习笔记 — 接口 — 接口与类型相互转换:在接口和类型之间转换”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
go语言学习笔记(十三)——接口类型
go语言学习笔记 — 接口 — 接口与类型相互转换:在接口和类型之间转换
go struct 成员变量后面再加个字符串是什么意思?_Go语言的学习笔记(第十章) 接口...
go语言学习笔记 — 接口 — 接口声明:接口是什么,接口的声明形式,开发中常见的接口写法
Go学习--interface(接口)
go语言学习笔记 — 接口 — 实现接口的条件(2):接口中的方法都被实现
go语言学习笔记 — 接口 — 接口的嵌套组合:把多个接口放到一个接口内
第07章 Go语言接口(interface),Golang接口(interface)
go 获取函数地址_Go语言基础--接口浅析
基于类型系统的面向对象编程语言Go

[关闭]
~ ~