Go语言中的类型断言,一般用于类型转换,但是这类转换是有限制的
- 类型断言,是将万能类型的
interface{}x转为自定类型T,格式为:x.(T) 
- 类型断言的必要条件就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{}。