空接口
什么是空接口
空接口是特殊形式的接口类型,普通的接口都有方法,而空接口没有定义任何方法口,也因此,我们可以说所有类型都至少实现了空接口。
type empty_iface interface {
}
每一个接口都包含两个属性,一个是值,一个是类型。
而对于空接口来说,这两者都是 nil。
eg:
package main
import (
"fmt"
)
//定义一个接口
type order interface{
countmoney() int
paymoney() string
}
type roastrice struct{
name string
quantity 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=1
fmt.Println(i)
i="hello"
fmt.Println(i)
i=false
fmt.Println(i)
/* 1
hello
false */
}
第二,如果想让你的函数可以接收任意类型的值 ,也可以使用空接口
eg:接收一个任意类型的值
func muyfunc(iface interface{}){
fmt.Println(iface)
}
func main(){
a := 10
b := "golang"
c := false
muyfunc(a)
muyfunc(b)
muyfunc(c)
/* 10
golang
false */
}
eg:接收任意多个类型的值
func muyfunc(ifaces ...interface{}){
for _,iface := range ifaces{
fmt.Println(iface)
}
}
func main(){
a := 10
b := "golang"
c := false
muyfunc(a,b,c)
/*
10
golang
false
*/
}
第三,你也定义一个可以接收任意类型的 array、slice、map、strcut
func main(){
any := make([]interface{},5)
any[0] = 11
any[1] = "hello world"
any[2] = []int{11,22,33,55}
for _,value := range any{
fmt.Println(value)
}
/* 11
hello 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 := 10
b := "hello"
myfunc(a)
myfunc(b)
}
//参数的类型是 int
//参数的类型是 string