空接口(interface)的用法和类型断言
- golang 中的接口可以不定义任何方法,没有定义任何方法的接口就是空接口。空接口表示 没有任何约束,因此任何类型变量都可以实现空接口
- 空接口在实际项目中用的是非常多的,用空接口可以表示任意数据类型
import (
"fmt"
"testing"
)
//空接口 表示没有任何约束 任意的类型都可以实现 空接口也可以直接当做类型来使用,可以表示任意类型
type A interface {
}
func TestInterfaceType(t *testing.T) {
var a A
var str = "hello world" //字符串实现A接口
a = str
fmt.Printf("%v---%T\n",a,a) //hello world---string
var num = 30 //int实现A接口
a = num
fmt.Printf("%v---%T\n",a,a) //30---int
var flag = true //bool实现A接口
a = flag
fmt.Printf("%v---%T\n",a,a) //true---bool
//空接口也可以直接当做类型来使用,可以表示任意类型
var b interface{}
b = 20
fmt.Printf("%v---%T\n",b,b) //20---int
b="你好"
fmt.Printf("%v---%T\n",b,b) //你好---string
b = false
fmt.Printf("%v---%T\n",b,b) //false---bool
//类型的断言
var n interface{}
n = "world"
_,ok := n.(string)
if ok{
fmt.Println(a)
}
//类型断言
}
空接口作为函数的参数
//空接口可以是方法的参数 表示接收任意类型的参数
func Show(a interface{}) {
fmt.Printf("%v---%T\n",a,a)
}
map 的值实现空接口
var m = make(map[string]interface{})
m["name"] = "小李"
m["age"] = 10
fmt.Println(m)
切片实现空接口
var silice = make([]interface{},2,2)
silice[0] = 1
silice[1] = "world"
fmt.Println(silice)
类型断言
- 一个接口的值(简称接口值)是由一个具体类型和具体类型的值两部分组成的。这两部分 别称为接口的动态类型和动态值
- 如果我们想要判断空接口中值的类型,那么这个时候就可以使用类型断言
x.(T)
x : 表示类型为 interface{}的变量
T : 表示断言 x 可能是的类型 - 该语法返回两个参数,第一个参数是 x 转化为 T 类型后的变量,第二个值是一个布尔值,若为 true 则表示断言成功,为 false 则表示断言失败
//类型的断言
var n interface{}
n = "world"
v,ok = n.(string)
if ok{
fmt.Println(a)
}
v.(type) 判断一个变量的类型 这个语句只能用在switch 语句里面
func MyDisplay(v interface{}) {
switch v.(type) {
case int:
fmt.Println("int")
case string:
fmt.Println("string")
case bool:
fmt.Println("bool")
default:
fmt.Println("传入错误...")
}
}
注意
- 因为空接口可以存储任意类型值的特点,所以空接口在 Go 语言中的使用十分广泛
- 只有当有两个或两个以上的具体类型必须以相同的方式进行处理时才需要定义接口。不要为了接口而写接口,那样只会增加不必要的抽象,导致不必要的运行
空接口和断言的应用
type Address struct {
Name string
Phone int
}
func TestMapInterface(t *testing.T) {
var userInfo = make(map[string]interface{})
userInfo["name"] = "lili"
userInfo["age"] = 20
userInfo["hobby"] = []string{"eat","sleep"}
fmt.Println(userInfo["name"])
fmt.Println(userInfo["age"])
fmt.Println(userInfo["hobby"])
//(userInfo["hobby"][1]) 错误的写法
//invalid operation: userInfo["hobby"][1] (type interface {} does not support indexing)
var hobby,_ = userInfo["hobby"].([]string)
fmt.Println(hobby[1])//sleep
var address = Address{
Name:"lili",
Phone: 15645327865,
}
userInfo["address"] = address
fmt.Println(address.Name)
//(userInfo["address"].Name) 错误的写法
//userInfo["address"].Name undefined (type interface {} is interface with no methods)
var addressMap,_ = userInfo["address"].(Address)
fmt.Println(addressMap.Phone)//15645327865
}