接口

接口语法 #

定义格式:
    type 接口名 interface{
        // 定义接口方法与返回值类型,可以无参,无返回值
        方法名1()   //定义无参,无返回值接口方法
        方法名2() 返回值类型
        方法名2() (返回值列表,多个用逗号分隔) // 定义无参、有返回值类型的接口方法
        方法名3(参数列表) 返回值类型 //定义有参,有返回值类型的接口方法
        方法名3(参数列表) (返回值列表,多个用逗号分隔)
        方法名4(变量名 变量类型,变量名2 变量类型) 返回值类型
        方法名4(变量名 变量类型,变量名2 变量类型) (返回值列表,多个用逗号分隔)
        接口名M
        接口名N  //表示当前接口继承接口名N,其实就是接口组合
                //但接口与接口之间不能互相组合,接口中也不能嵌入结构体
    }

定义空接口(标识性接口): type 接口名 interface{}
        定义空接口示例: type JellyEmpty interface{}

匿名接口:
    var 变量名 interface{
        方法名1()
        方法名2() 返回值类型
        方法名3() (返回值列表,多个用逗号分隔)
        方法名4(参数列表) 返回值类型
        方法名N(参数列表) (返回值列表,多个用逗号分隔)
    }

接口名命名规范:
    一般以er结尾,例如:io包中的常用接口名Writer、Closer、Reader、io.ReadWriter

备注:同一包下接口名不能重复,
    大写字母开头的是公共的(认为其它语言的public),
    小写字母开头的是私有的(认为其它语言的private)
    参数列表和返回值列表中的参数变量名可以被忽略

接口类型变量 #

声明接口类型变量: var 变量名 接口名
接口变量只声明未赋值的默认值为nil
示例1:
  var a interface{} 表接收任意类型值变量
  fmt.Printf("%v \n", a) //<nil>
示例2:
  var a io.ReadWriter
  fmt.Printf("%v \n", a) //<nil>

接口断言 #

格式1: 接口变量2,是否断言正确 := 接口变量1.(接口名)
    if 接口变量2,isOk := 接口变量1.(接口名);isOk {
        //todo
    }
格式2:
    接口变量2 := 接口变量1.(接口名)

    var 接口变量2 interface{} = 结构体变量
    接口变量2 = 接口变量1.(接口名)
格式2的语法:如果"接口变量1"不是接口的类型,那么直接抛painc错误

接口定义与使用示例 #

参数列表和返回值列表中的参数变量名被忽略示例:
package main
import "fmt"
//定义接口
type MyI01 interface {
	Writer(string) error  //等价 Writer(abc string) error
}
//定义结构体
type MyStruct01 struct {
	name string
}
//结构体添加方法
func (this MyStruct01) Writer(str string) error {
	fmt.Println(str, this.name)
	return nil
}

func main()  {
    var myIObj01 MyI01 //接口类型变量,默认值nil
    my01 := MyStruct01{name:"admin"}
    my01.Writer("你好,") //你好, admin
    myIObj01 = my01
    myIObj01.Writer("账号名:") //账号名: admin
}

任意类型变量 #

var i interface{} = 99 // i可以是任何类型值,因此后面可以接收任意类型的赋值
//或者 var i interface{}  未赋值则默认值为nil
	i = 44.09
	i = "All"

fmt.Println(i) //All

接口变量默认值nil #

package main
import "fmt"
type MyI01 interface {
	Writer(string) error
}

func main() {
	var myIObj01 MyI01
	fmt.Printf("%T\n", myIObj01) //<nil>
	if(myIObj01 == nil) {
		fmt.Println("变量myIObj01值为nil")
	}
}

接口断言示例 #

package main

import (
	"fmt"
)

type MyI01 interface {
	Writer(string) error
}
type S01 struct {

}

func (this *S01) Writer(str string) error  {
	fmt.Println(str)
	return nil
}
func main() {
	var myIObj01 MyI01
	fmt.Printf("%T\n", myIObj01) //<nil>
	if(myIObj01 == nil) {
		fmt.Println("变量myIObj01值为nil")
	}
	//接口断言: 接口变量2,是否断言正确 := 接口变量1.(接口名)
	if o,isOk := myIObj01.(MyI01); isOk {
		o.Writer("是MyI01变量")
	} else {
		fmt.Println("不是MyI01接口变量") //打印:不是MyI01接口变量, 因为myIObj01只是声明
	}
	var myIObj02 MyI01
	myIObj02 = &S01{}
	if o,isOk := myIObj02.(MyI01); isOk {
		o.Writer("是myIObj02变量") //是myIObj02变量
		myIObj02.Writer("hello") //hello
	} else {
		fmt.Println("不是myIObj02接口变量")
	}

	var myIObj03 interface{}
	myIObj03 = &S01{}
	if o,isOk := myIObj03.(MyI01); isOk {
		o.Writer("是myIObj03变量") //是myIObj03变量
	} else {
		fmt.Println("不是myIObj03接口变量")
	}

}

匿名接口示例 #

package main
import (
	"fmt"
)
type Xyz struct {
	name string
}

func (t Xyz) print()  {
	fmt.Println(t.name)
}
func main() {
    //匿名接口类型
	var a interface{
		print()
	}
	//实例化结构体
	a = Xyz{name:"tom"}
	a.print() //tom
}


Build by Loppo 0.6.15