Golang类型断言

简介: Golang类型断言

系列文章:

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)

目录
相关文章
|
4月前
|
存储 Go
Golang底层原理剖析之slice类型与扩容机制
Golang底层原理剖析之slice类型与扩容机制
61 0
|
10月前
|
关系型数据库 Go PostgreSQL
golang pgx自定义PostgreSQL类型
golang的pgx驱动提供了大约70种PostgreSQL类型支持,但还是有一些类型没有涵盖,本文介绍如何自己编写代码支持特殊的类型。
|
11月前
|
安全 Go
Golang 语言的编程技巧之类型
Golang 语言的编程技巧之类型
51 0
|
11月前
|
存储 安全 编译器
Golang 语言中 map 的键值类型选择,它是并发安全的吗?
Golang 语言中 map 的键值类型选择,它是并发安全的吗?
58 0
|
24天前
|
Go
Golang语言基础之接口(interface)及类型断言
这篇文章是关于Go语言中接口(interface)及类型断言的详细教程,涵盖了接口的概念、定义、实现、使用注意事项以及类型断言的多种场景和方法。
23 4
|
24天前
|
Go
Golang语言基础数据类型之字符类型
这篇文章介绍了Go语言中的字符类型,包括字符概述、byte和rune类型的定义、转义字符的使用以及如何遍历字符串获取字符的示例。
11 0
|
11月前
|
Go
Golang 语言怎么打印结构体指针类型字段的值?
Golang 语言怎么打印结构体指针类型字段的值?
242 0
|
11月前
|
存储 安全 Go
Golang 语言 method 接收者使用值类型和指针类型的区别
Golang 语言 method 接收者使用值类型和指针类型的区别
47 0
|
4月前
|
存储 缓存 Go
Golang底层原理剖析之类型系统,接口与类型断言
Golang底层原理剖析之类型系统,接口与类型断言
81 2
|
4月前
|
Go
Golang随笔之自动类型推导[:=]踩坑
Golang随笔之自动类型推导[:=]踩坑
30 0