关于我们

质量为本、客户为根、勇于拼搏、务实创新

< 返回新闻公共列表

Golang类型断言

发布时间:2023-06-26 22:00:27

系列文章:

golang实现多态

golang利用组合实现继承,和php或java面向对象的继承有何不同

Golang类型断言

golang之interface入门

interface,鸭子类型与泛型


所谓 类型断言(type assertion):

cannot convert a (type interface{}) to type string: need type assertion


直接转换


如果明确知道a的类型,可以直接转换:

package main  import "fmt"  func main() {  var i interface{}  i = "cuishuang"  f(i) }  func f(a interface{}) string {  fmt.Println(a)   return a.(string) }

   

则编译通过.


格式为 a.(对应的类型)

但如果"()"里面的类型不对,则会直接panic

package main  import "fmt"  func main() {  var i interface{}  i = "cuishuang"  f(i) }  func f(a interface{}) string {  fmt.Println(a.(int))   return "" }

   

输出为:

panic: interface conversion: interface {} is string, not int  goroutine 1 [running]:

   

OK判别式


如上,如果类型不一致,会直接panic。所以一般在断言时,都要用OK判别式的格式(哪怕只是value, _ := a.(float32),起码这样不会panic了)

如:

package main  import "fmt"  func main() {  var i interface{}  i = "cuishuang"  f(i) }  func f(a interface{}) string {   value, _ := a.(float32)   fmt.Println("value ", value)   return "" }

   

输出为:value 0


而如果:

package main  import "fmt"  func main() {  var i interface{}  i = "cuishuang"  f(i) }  func f(a interface{}) string {   value := a.(float32)   fmt.Println("value ", value)   return "" }

   

则会

panic: interface conversion: interface {} is string, not float32  goroutine 1 [running]: main.f({0x10071baa0?, 0x10072c748?})  /Users/fliter/go/src/shuang/interfacee/assert.go:13 +0xb4 main.main()  /Users/fliter/go/src/shuang/interfacee/assert.go:8 +0x2c exit status 2

   

golangci-lint有一个检查项 forcetypeassert,用来强制类型断言,检查interface转换有没有进行类型校验


在断言时进行判断:

  • 如果断言失败,那么ok的值将会是false.
  • 如果断言成功, ok的值将会是true, 同时value就是所期待的正确的值
package main  import "fmt"  func main() {  var i interface{}  i = "cuishuang"  f(i) }  func f(a interface{}) string {  value,ok := a.(int)   if ok {  fmt.Println(a.(int)) //a.(int) 即 value  fmt.Println(value)  } else {  fmt.Println("i中不是int类型")  }   return "" }

   

输出为:

i中不是int类型

   

配合switch语句进行判断

package main  import "fmt"  func main() {  var i interface{}  i = "cuishuang"  f(i) }  func f(a interface{}) string {   switch val := a.(type) {  default:  fmt.Printf("unexpected type %T", val) // %T prints whatever type t has  break  case bool:  fmt.Printf("boolean: %t\n", val) // t has type bool  break  case int:  fmt.Printf("integer: %d\n", val) // t has type int  break  case string:  fmt.Printf("string: %s\n", val) // t has type string  break  case *bool:  fmt.Printf("pointer to boolean: %t\n", *val) // t has type *bool  break  case *int:  fmt.Printf("pointer to integer: %d\n", *val) // t has type *int   case *string:  fmt.Printf("pointer to string: %s\n", *val) // t has type *string  break   }   return "" }

   

输出为:

string: cuishuang

   

参考:

深入Go语言 - 6

golang类型断言的使用(Type Assertion)


/template/Home/leiyu/PC/Static