五、空接口

空接口是特殊形式的接口类型,普通的接口都有方法,而空接口没有定义任何方法口,也因此,我们可以说所有类型都至少实现了空接口。

package main

import "fmt"

//空接口的使用
func main() {
	//第一,通常我们会直接使用 interface{} 作为类型声明一个实例,而这个实例可以承载任意类型的值。
	//声明一个空接口实例
	var i interface{}
	//存int
	i=1
	fmt.Println(i)
	//存字符串
	i="hello"
	fmt.Println(i)

	//第二,如果想让你的函数可以接收任意类型的值 ,也可以使用空接口
	a := 10
	b := "hello"
	c := true
	myfunc(a)
	myfunc(b)
	myfunc(c)

	//第三,你也定义一个可以接收任意类型的 array、slice、map、strcut,例如这边定义一个切片
	any := make([]interface{}, 5)
	any[0] = 11
	any[1] = "hello world"
	any[2] = []int{11, 22, 33, 44}
	for _, value := range  any{
		fmt.Println(value)
	}

	//注意:(1)把一个空接口类型的对象,再赋值给一个固定类型(比如 int, string等类型)的对象赋值,是会报错的。
	//(2)当空接口承载数组和切片后,该对象无法再进行切片
	//(3)当你使用空接口来接收任意类型的参数时,它的静态类型是 interface{},但动态类型(是 int,string 还是其他类型)我们并不知道,因此需要使用类型断言。
	c := 10
	d := "hello"
	myfunc2(c)
	myfunc2(d)
}

//接收一个任意类型的值示例
func myfunc(ifac interface{}){
	fmt.Println(ifac)
}

func myfunc2(i interface{})  {

	switch i.(type) {
	case int:
		fmt.Println("参数的类型是 int")
	case string:
		fmt.Println("参数的类型是 string")
	}
}

六、接口中的一些规则

1、对方法的调用限制

package main

import "fmt"

type Phone interface {
    call()
}

type iPhone struct {
    name string
}

func (phone iPhone)call()  {
    fmt.Println("Hello, iPhone.")
}

func (phone iPhone)send_wechat()  {
    fmt.Println("Hello, Wechat.")
}

func main() {
    var phone Phone
    phone = iPhone{name:"ming's iphone"}
    phone.call()
    phone.send_wechat()
}
phone.send_wechat

2、调用函数时的隐式转换

Go 语言中的函数调用都是值传递的,变量会在方法调用前进行类型转换。

import (
    "fmt"
)

func printType(i interface{})  {

    switch i.(type) {
    case int:
        fmt.Println("参数的类型是 int")
    case string:
        fmt.Println("参数的类型是 string")
    }
}

func main() {
    a := 10
    printType(a)
}

但是将该代码搬到外面来会进行报错,因为当一个函数接口 interface{} 空接口类型时,我们说它可以接收什么任意类型的参数。Go 就是把传入函数的参数值(注意:Go 语言中的函数调用都是值传递的)的类型隐式的转换成 interface{} 类型。

package main

import "fmt"
func main() {
    a := 10

    switch a.(type) {
    case int:
        fmt.Println("参数的类型是 int")
    case string:
        fmt.Println("参数的类型是 string")
    }
}

如何进行接口类型的显示转换

package main

import "fmt"


func main() {
    a := 10

    switch interface{}(a).(type) {
    case int:
        fmt.Println("参数的类型是 int")
    case string:
        fmt.Println("参数的类型是 string")
    }
}