Golang类型断言

Go语言中的类型断言,一般用于类型转换,但是这类转换是有限制的

  1. 类型断言,是将万能类型的interface{}x转为自定类型T,格式为:x.(T)
  2. 类型断言的必要条件就x是接口类型,非接口类型的x不能做类型断言

接下来,我们就来动手实践一番

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package main

import (
"fmt"
)

type Person struct {
Name string
}

func speak(p interface{}) {
person := p.(Person)
fmt.Println(person.Name)
}

func main() {
p := Person{Name: "Bob"}
speak(p)
}

speak里面的参数为interface{},在使用时,我们使用类型断言interface{}转换为Person。这种断言是基础类型,但是有时候,我们可能会断言失败。我们新建一个类型来看看现象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package main

import (
"fmt"
)

type Person struct {
Name string
}

type Staff struct {
Name string
}

func speak(p interface{}) {
staff := p.(Staff)
fmt.Println(staff.Name)
}

func main() {
p := Person{Name: "Bob"}
speak(p)
}

这时候会报错,并提示

1
panic: interface conversion: interface {} is main.Person, not main.Staff

这时候,我们需要安全的转换,如果转换失败则不往下面执行

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
package main

import (
"fmt"
)

type Person struct {
Name string
}

type Staff struct {
Name string
}

func speak(p interface{}) {
staff, ok := p.(Staff)
if ok {
fmt.Println(staff.Name)
}
}

func main() {
p := Person{Name: "Bob"}
speak(p)
}

类型断言虽然好用,但是如果因为结构体的字段过多,会导致转换效率比较低,而且不同的数据类型的转换效率也不同。有网友提到,使用指针并转换回相同的结构指针,则会大大提高转换效率,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

import (
"fmt"
)

type Person struct {
Name string
}

func speak(p interface{}) {
person, ok := p.(*Person)
if ok {
fmt.Println(person.Name)
}
}

func main() {
p := &Person{Name: "Bob"}
speak(p)
}

虽然interface{}用起来很爽,但是如果使用不得当,则会对我们的程序造成性能影响。所以,我们要适当、恰当的使用interface{}

作者

eyiadmin

发布于

2022-08-23

更新于

2024-05-31

许可协议

评论