接口语法 #
定义格式:
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
}