空接口
什么是空接口
空接口是特殊形式的接口类型,普通的接口都有方法,而空接口没有定义任何方法口,也因此,我们可以说所有类型都至少实现了空接口。
type empty_iface interface {
}
每一个接口都包含两个属性,一个是值,一个是类型。
而对于空接口来说,这两者都是 nil。
eg:
package mainimport ("fmt"
)//定义一个接口
type order interface{countmoney() intpaymoney() string
}type roastrice struct{name stringquantity int price int
}func main(){rice := roastrice{"烤饭",5,2,}fmt.Printf("type: %T,value: %v\n",rice,rice)//定义一个空接口var i interface{}fmt.Printf("type: %T,value: %v\n",i,i)/* type: main.roastrice,value: {烤饭 5 2}type: <nil>,value: <nil>*/
}
空接口的作用
第一,通常我们会直接使用 interface{} 作为类型声明一个实例,而这个实例可以承载任意类型的值。
//如下,空接口可以存int,字符串,布尔值...
func main(){//定义一个空接口var i interface{}i=1fmt.Println(i)i="hello"fmt.Println(i)i=falsefmt.Println(i)/* 1hellofalse */
}
第二,如果想让你的函数可以接收任意类型的值 ,也可以使用空接口
eg:接收一个任意类型的值
func muyfunc(iface interface{}){fmt.Println(iface)
}func main(){a := 10b := "golang"c := falsemuyfunc(a)muyfunc(b)muyfunc(c)/* 10golangfalse */
}
eg:接收任意多个类型的值
func muyfunc(ifaces ...interface{}){for _,iface := range ifaces{fmt.Println(iface)}
}
func main(){a := 10b := "golang"c := falsemuyfunc(a,b,c)/*10golangfalse*/
}
第三,你也定义一个可以接收任意类型的 array、slice、map、strcut
func main(){any := make([]interface{},5)any[0] = 11any[1] = "hello world"any[2] = []int{11,22,33,55}for _,value := range any{fmt.Println(value)}/* 11hello world[11 22 33 55]<nil><nil> */
}
使用空接口的注意事项
- 空接口可以承载任意值,但不代表任意类型就可以承接空接口类型的值
从实现的角度看,任何类型的值都满足空接口。因此空接口类型可以保存任何值,也可以从空接口中取出原值。
但要是你把一个空接口类型的对象,再赋值给一个固定类型(比如 int, string等类型)的对象赋值,是会报错的。
- 空接口承载数组和切片后,该对象无法再进行切片
- 当你使用空接口来接收任意类型的参数时,它的静态类型是 interface{},但动态类型(是 int,string 还是其他类型)我们并不知道,因此需要使用类型断言。
func myfunc(i interface{}) {switch i.(type) {case int:fmt.Println("参数的类型是 int")case string:fmt.Println("参数的类型是 string")}
}
func main() {a := 10b := "hello"myfunc(a)myfunc(b)
}//参数的类型是 int
//参数的类型是 string