这几天一直在看GO语言知识,其中对接口的知识点有点模糊,所以整理一下。
1.先看一下接口的定义
type 接口名 interface{
方法名1(参数列表1) 返回值1
方法名2(参数列表2) 返回值2
...
}
注意:接口里的方法可以为空,也就是一个空接口。下面举个例子:
//定义People接口,有一个说名字的方法
type People interface {
SayName() string
}
//声明了一个People类型的变量p
var p People
2.接口的实现
如果一个对象实现了接口中的所有方法,则说这个对象实现了这个接口。Go语言中的不同类型可以实现同一个接口。举例子:
//定义一个People接口
type People interface {
SayName() string
}
//定义一个学生类型
type Student struct {
Name string
}
//定义一个工人类型
type Worker struct {
Name string
}
//学生类型实现SayName方法
func (s Student)SayName() string {
return s.Name
}
//工人类型实现SayName方法
func (w Worker)SayName() string {
return w.Name
}
func main() {
var p People
student:= Student{Name:"张三"}
p = student
fmt.Println(p.SayName())
fmt.Printf("%T\n",p)
worker:=Worker{Name:"小王"}
p = worker
fmt.Println(p.SayName())
fmt.Printf("%T\n",p)
}
以上会输出
张三
main.Student
小王
main.Worker
分析一下,定义了一个接口类型的People,里面又SayName()方法,学生类型Student,然后定义了学生类型的方法,由于People接口只有一个方法,所以学生类型实现了People接口,main方法中p=student才不会报错,如果People中还有个Sing()唱歌的方法,学生类型没有Sing()方法,p=student会提示:cannot use student (type Student) as type People in assignment:
Student does not implement People (missing Sing method)。工人类型和学生类型一样,说明了不同类型可以实现同一个接口。
3.如何判断是否实现了接口
//定义一个People接口
type People interface {
SayName() string
}
//定义一个学生类型
type Student struct {
Name string
}
//学生类型实现SayName方法
func (s Student)SayName() string {
return s.Name
}
//检查结构体都实现了接口了没有
func checkPepole(tmp interface{}) {
if _,ok:=tmp.(People);ok {
fmt.Println("Student implements People")
}
}
func main() {
student:= Student{Name:"张三"}
checkPepole(student)
}
4.空接口
如果一个接口里面没有任何方法,则称为空接口,任何类型都实现了空接口,所以任何类型都可以给空接口赋值。
func main(){
// 定义tmp为空接口
var tmp interface{}
var i int = 5
var s string = "Hello world"
type Student struct{
Name string
}
student:=Student{Name:"张三"}
// tmp可以存储任意类型的数值
tmp = i
tmp = s
tmp = student
}
5.接口断言。
既然空接口可以存储任何类型的数据,就需要判断出变量的具体类型。
接口断言有两种方法,第一种是x.(type),x为接口类型的变量,返回变量的类型,这种方法需要再switch case语句中使用。第二种是x.(T),x为接口类型的变量,T为x可能的类型,变量的值和是否是这个类型的结果。
//断言-switch判断
func JudgeTypeSwith(v interface{}) {
switch v.(type) {
case int:
fmt.Println("int类型")
case string:
fmt.Println("string类型")
case float64:
fmt.Println("float64类型")
default:
fmt.Println("unknown type")
}
}
//断言 ok
func JudgeTypeComma(v interface{}){
if _,ok:=v.(string);ok {
fmt.Println("string 类型")
}else if _,ok :=v.(int);ok {
fmt.Println("int 类型")
}else if _,ok :=v.(Student);ok{
fmt.Println("Student 类型")
}else{
fmt.Println("未知类型")
}
}
func main(){
var a int
a = 10
JudgeTypeSwith(a)
var b string
b = "is a string"
JudgeTypeComma(b)
}