⽬录
1、空接⼝2、类型断⾔3、结构体值接收者和指针接收者实现接⼝的区别4、⼀个结构体实现多个接⼝5、接⼝嵌套6、Golang中空接⼝和类型断⾔使⽤细节1、空接⼝
Golang 中的接⼝可以不定义任何⽅法,没有定义任何⽅法的接⼝就是空接⼝。空接⼝表⽰,没有任何约束,因此任何类型变量都可以实现空接⼝。空接⼝在实际项⽬中⽤的是⾮常多的,⽤空接⼝可以表⽰任意数据类型
func main() {
// 定义⼀个空接⼝ x, x 变量可以接收任意的数据类型var x interface{}s := \"你好 golang\"x = s
fmt.Printf(\"type:%T value:%v\\n\i := 100x = i
fmt.Printf(\"type:%T value:%v\\n\b := truex = bfmt
1 、空接⼝作为函数的参数: 使⽤空接⼝实现可以接收任意类型的函数参数
// 空接⼝作为函数参数func show(a interface{}) {
fmt.Printf(\"type:%T value:%v\\n\}
2 、map 的值 实现空接⼝: 使⽤空接⼝实现可以保存任意值的字典
// 空接⼝作为 map 值
var studentInfo = make(map[string]interface{})studentInfo[\"name\"] = \"张三\"studentInfo[\"age\"] = 18
studentInfo[\"married\"] = falsefmt.Println(studentInfo
3 、切⽚实现空接⼝
var slice = []interface{}{\"张三\fmt.Println(slice)
2、类型断⾔
⼀个接⼝的值(简称接⼝值)是由⼀个具体类型和具体类型的值两部分组成的。这两部分分别称为接⼝的动态类型和动态值。
如果我们想要判断空接⼝中值的类型,那么这个时候就可以使⽤类型断⾔,其语法格式:x.(T)其中:
• x : 表⽰类型为 interface{}的变量• T : 表⽰断⾔ x 可能是的类型。
该语法返回两个参数,第⼀个参数是 x 转化为 T 类型后的变量,第⼆个值是⼀个布尔值,若为 true 则表⽰断⾔成功,为 false 则表⽰断⾔失败
例如:
func main() {var x interface{}x = \"Hello golnag\"v, ok := x.(string)if ok {
fmt.Println(v)} else {
fmt.Println(\"类型断⾔失败\")}}
上⾯的⽰例中如果要断⾔多次就需要写多个 if 判断,这个时候我们可以使⽤ switch 语句来实现:
注意:类型.(type)只能结合 switch 语句使⽤
func justifyType(x interface{}) {switch v := x.(type) {case string:
fmt.Printf(\"x is a string,value is %v\\n\case int:
fmt.Printf(\"x is a int is %v\\n\case bool:
fmt.Printf(\"x is a bool is %v\\n\default:
fmt.Println(\"unsupport type!\")}}
因为空接⼝可以存储任意类型值的特点,所以空接⼝在 Go 语⾔中的使⽤⼗分⼴泛。
关于接⼝需要注意的是: :只有当有两个或两个以上的具体类型必须以相同的⽅式进⾏处理时才需要定义接⼝。不要为了接⼝⽽写接⼝,那样只会增加不必要的抽象,导致不必要的运⾏时损耗。
3、结构体值接收者和指针接收者实现接⼝的区别
值接收者:
如果结构体中的⽅法是值接收者,那么实例化后的结构体值类型和结构体指针类型都可以赋值给接⼝变量
package mainimport \"fmt\"
type Usb interface {Start()Stop()}
type Phone struct {Name string}
func (p Phone) Start() {
fmt.Println(p.Name, \"开始⼯作\")}
func (p Phone) Stop() {fmt.Println(\"phone 停⽌\")}
func main() {
phone1 := Phone{Name: \"⼩⽶⼿机\}
var p1 Usb = phone1 //phone1 实现了 Usb 接⼝ phone1 是 Phone 类型p1.Start() //⼩⽶⼿机 开始⼯作phone2 := &Phone{Name: \"苹果⼿机\}
var p2 Usb = phone2 //phone2 实现了 Usb 接⼝ phone2 是 *Phone 类型p2.Start() //苹果⼿机 开始⼯作}
指针接收者:
如果结构体中的⽅法是指针接收者,那么实例化后结构体指针类型都可以赋值给接⼝变量,结构体值类型没法赋值给接⼝变量
package mainimport \"fmt\"
type Usb interface {Start()Stop()}
type Phone struct {Name string}
func (p *Phone) Start() {
fmt.Println(p.Name, \"开始⼯作\")}
func (p *Phone) Stop() {fmt.Println(\"phone 停⽌\")}
func main() {/*
错误写法
phone1 := Phone{Name: \"⼩⽶⼿机\}
var p1 Usb = phone1p1.Start()*/
//正确写法
phone2 := &Phone{Name: \"苹果⼿机\}
var p2 Usb = phone2 //phone2 实现了 Usb 接⼝ phone2 是 *Phone 类型p2.Start() //苹果⼿机 开始⼯作}
4、⼀个结构体实现多个接⼝
Golang 中⼀个结构体也可以实现多个接⼝
package mainimport \"fmt\"
type AInterface interface {GetInfo() string}
type BInterface interface {SetInfo(string, int)}
type People struct {Name stringAge int}
func (p People) GetInfo() string {
return fmt.Sprintf(\"姓名:%v 年龄:%d\}
func (p *People) SetInfo(name string, age int) {p.Name = namep.Age = age}
func main() {
var people = &People{Name: \"张三\Age: 20,}
// people 实现了 AInterface 和 BInterfacevar p1 AInterface = peoplevar p2 BInterface = people
fmt.Println(p1.GetInfo())p2.SetInfo(\"李四\fmt.Println(p1.GetInfo())}
5、接⼝嵌套
接⼝与接⼝间可以通过嵌套创造出新的接⼝
package mainimport \"fmt\"
type SayInterface interface {say()}
type MoveInterface interface {move()}
// 接⼝嵌套
type Animal interface {SayInterfaceMoveInterface}
type Cat struct {name string}
func (c Cat) say() {fmt.Println(\"喵喵喵\")}
func (c Cat) move() {fmt.Println(\"猫会动\")}
func main() {var x Animal
x = Cat{name: \"花花\x.move()x.say()}
6、Golang中空接⼝和类型断⾔使⽤细节
使⽤空接⼝定义⼀个map类型的数据,其数据中是切⽚或者结构体,其通过索引拿到对应切⽚内容的值,出现错误,必须通过类型断⾔的形式拿到对应的数据,结构体同理,案例如下:
package mainimport \"fmt\"
type Address struct { Name string Phone int}
// Golang中空接⼝和类型断⾔使⽤细节func main() {
var userinfo = make(map[string]interface{}) userinfo[\"username\"] = \"张三\" userinfo[\"age\"] = 20
userinfo[\"hobby\"] = []string{\"睡觉\吃饭\ fmt.Println(userinfo[\"age\"]) fmt.Println(userinfo[\"hobby\"])
// fmt.Println(userinfo[\"hobby\"][1]) //interface {} does not support indexing var address = Address{ Name: \"李四\
Phone: 1521242141, }
fmt.Println(address.Name) //李四 userinfo[\"address\"] = address
fmt.Println(userinfo[\"address\"]) //{李四 1521242141}
// var name = userinfo[\"address\"].Name //type interface {} is interface with no methods // fmt.Println(name)
hobby2, _ := userinfo[\"hobby\"].([]string) fmt.Println(hobby2[1]) //吃饭
address2, _ := userinfo[\"address\"].(Address)
fmt.Println(address2.Name, address2.Phone) //李四 1521242141}
到此这篇关于golang中的空接⼝使⽤的⽂章就介绍到这了,更多相关golang空接⼝使⽤内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
因篇幅问题不能全部显示,请点此查看更多更全内容