Golang 空接口 & 类型断言
空接口,是指没有定义任何方法的接口类型。
所以,任何类型,都可以被看作是实现了空接口,同理,空接口类型的变量,可以存储任意类型的( 接口 )值
func main() { var x any // 空接口类型的变量,可以存储任意类型的值 x = 100 fmt.Printf("type:%T value:%v \n", x, x) // type:int value:100 x = "hello" fmt.Printf("type:%T value:%v \n", x, x) // type:string value:hello x = true fmt.Printf("type:%T value:%v \n", x, x) // type:bool value:true x = struct { Name string }{"小明"} fmt.Printf("type:%T value:%v \n", x, x) // type:struct { Name string } value:{小明} } type any interface { // 定义一个空接口 }「 声明方式( 推荐 )」通常,在使用空接口类型时,不必使用 type 关键字,直接使用 interface{} 即可
var x interface{} // 声明一个空接口类型变量x「 应用 」简单来说就是,空接口,可以存储任意类型的值
// 空接口,作为函数参数,可以接收任意类型的数据 func show(a interface{}) { fmt.Printf("type:%T value:%v\n", a, a) // 问题是,接口值可能被赋值为任意类型的值,So,如何获取其具体存储的数据呢 ? } // 空接口,作为 map 的值,可以保持任意类型的值 var stu = make(map[string]interface{}) stu["name"] = "小明" stu["age"] = 20 fmt.Println(stu) // map[age:20 name:小明]
类型断言
所谓 “ 类型断言 ”,可以这样理解:接口值可能被赋值为任意类型的数据,而,Golang 中使用的是强类型,
- 也就是说:接口值,由 “类型” 和 “值” 组成,这两部分会根据存入值的不同而发生变化
所以,我们在对接口值进行实际操作之前,通常需要对其进行 “类型判断”,才能进行后续的操作
// 基本语法 x.(T) // x:表示接口类型的变量;T:表示断言 x 可能是的类型 // 代码示例 func main() { var x interface{} x = &Dog{"小白"} v, ok := x.(*Dog) // 返回两个参数,第一个参数是 x 转化为 T 类型后的变量 // 第二个参数,是一个布尔值,若为true,则表示断言成功,为 false,则表示断言失败 if ok { fmt.Println("断言成功") fmt.Println(v.Name) // 小白 // 结构体,才能如此调用 } else { fmt.Println("断言失败") } } // 定义一个结构体 type Dog struct { Name string }如果对于一个接口值,有多个实际类型需要判断,可以使用 switch 语句
func justifyType(x interface{}) { switch v := x.(type) { case string: fmt.Printf("x is a string,value is %v\n", v) case int: fmt.Printf("x is a int is %v\n", v) case bool: fmt.Printf("x is a bool is %v\n", v) default: fmt.Println("unsupport type!") } }