GO成神之路:接口interface|Go主题月

接口interface

接口是一组方法签名,所有实现了该签名的子类都可以赋值给这个接口变量。

go中有两种接口的使用场景:1. 用作类型签名,2. 空接口(无方法签名)

用作类型签名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
go复制代码type Abser interface {
Abs() float64
}
type Vertex struct {
X, Y float64
}

func (v *Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func main() {
var a Abser
v := Vertex{3, 4}
a = &v // a *Vertex 实现了 Abser
// 下面一行,v 是一个 Vertex(而不是 *Vertex)
//v.Abs()调用时实际被转成了(&v).Abs()
// 所以没有实现 Abser
// 下面为错误代码
a = v

fmt.Println(a.Abs())
}

空接口

空接口就是没有任何方法签名的接口,它可以接收任意类型的值

1
2
3
4
5
6
7
8
9
go复制代码func main() {
var i interface{}
i = 1
i = 1.1
i = "1"
i = map[string]interface{}{}
i = []int{}
i = true
}

interface与nil

接口类似于下面这样一个结构体,一个接口变量记录了它实际指向的值和这个值的类型

1
2
3
4
go复制代码type interface struct{
data interface{}
type Type
}

下面这个例子,给一个接口类型赋值一个bool值,实际上接口内部存储了两个值,一个是具体的值,一个是类型

1
2
3
go复制代码var i interface{}
i = true
fmt.Printf("%v %T",i,i) // true bool

不要判断interface是否为nil

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
go复制代码func main() {

var i interface{}
if i == nil {
log.Println("is nil") // is nil
}
var ipeople *IPeople
i = ipeople
log.Printf("%v %T", i, i) // nil nil
var people *People
i = people
if people == nil {
log.Println("people is nil") // people is nil
}
if i == nil {
log.Println("i is nil")
} else {
log.Println("i is not nil") // i is not nil
log.Printf("%v %T", i, i) // nil *main.People
}
var people2 People

log.Printf("%v %T", people2, people2) //{} main.People
}

type People struct {
}

type IPeople interface{}

使用断言判断接口是否为nil

语法:v,ok:=i.(type)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
go复制代码func main() {
var i interface{}
i = 1

v, ok := i.(int)
log.Println(v, ok) // 1 true

var people *People
i = people
people, ok = i.(*People)
log.Println(people, ok) // <nil> true

var ipeople *IPeople
i = ipeople
ipeople, ok = i.(*IPeople)
log.Println(ipeople, ok) // <nil> true

var people1 People
var ipeople1 IPeople
i = people1
people1, ok = i.(People)
log.Println(ipeople, ok) // <nil> true
i = ipeople1
ipeople1, ok = i.(IPeople)
log.Println(ipeople1, ok) // <nil> false
if ok && ipeople==nil{
// do...
}
}
type People struct{}
type IPeople interface{}

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%