前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go之断言类型(assert type)

Go之断言类型(assert type)

作者头像
灰子学技术
发布2023-10-30 15:51:02
1160
发布2023-10-30 15:51:02
举报
文章被收录于专栏:灰子学技术灰子学技术

1.背景介绍:

笔者最近在使用一个数据结构实现多个接口,但是却发现想要在一段时间内转换成接口1,另外一段时间转换成接口2,所以也就使用到了断言类型。在看过断言类型之后,觉得还是很有必要讲一讲这个断言类型,于是便有了这篇文章。

2. 断言类型介绍

接口类型提供一种,将接口类型转换成具体类型的转换方法,也就是断言类型(assert type)。使用方法如下所示:

1)语法一

代码语言:javascript
复制
t := i.(T)

解释说明:

T:表示的是具体的数据类型,i:表示的是接口变量i,t:表示的是转换之后的变量。

功能介绍

这个语句实现的功能是:将接口变量i按照类型T转换成t,其中t中的值是i转换得来的,一旦转换不成功就会触发一个panic。

2)除此之外还有另外一个写法:

代码语言:javascript
复制
t, ok := i.(T)

功能介绍:

表达式里面多了一个ok,实现的功能是:将接口i按照类型T转换成t,如果类型匹配ok=true,如果类型不匹配,ok=false。改语句不会触发panic。

3)例子如下所示:

代码语言:javascript
复制
package main

import "fmt"

func main() {
  var i interface{} = "hello world"

  str := i.(string) // 1.接口i是string类型,会将"hello world"赋值给str
  fmt.Println(str)

  s, ok := i.(string) // 2.接口类型是string,会将"hello world"赋值给s,并且ok=true
  fmt.Println(s, ok)

  idx, ok := i.(int) // 3.接口类型不是int,ok=false,idx不会从i获取到数值
  fmt.Println(idx, ok)
  
  idx = i.(int) // 4.接口i不是int类型,会触发panic
  fmt.Println(idx)
}

Output:

代码语言:javascript
复制
hello world
hello world true
0 false
panic: interface conversion: interface {} is string, not int

goroutine 1 [running]:
main.main()
  /tmp/sandbox277669744/prog.go:17 +0x1f4

3.断言类型的使用场景:

1)T的类型是具体类型

类型断言检查x的动态类型是否等于具体类型T。如果检查成功,类型断言返回的结果是x的动态值,其类型是T。

例子可以参考2中的例子,并无特别的不同之处。

2)T的类型是接口类型

类型断言检查x的动态类型是否满足T。如果检查成功,x的动态值不会被提取,返回值是一个类型为T的接口值。换句话说,到接口类型的类型断言,改变了表达式的类型,改变了(通常是扩大了)可以访问的方法,且保护了接口值内部的动态类型和值。

例子:

代码语言:javascript
复制
package main

import (
    "fmt"
)

type I interface {
    walk()
}
type J interface {
    fly()
}
type A struct{}

func (a A) walk() {
    fmt.Println("walk!")
}
func (a A) fly() {
    fmt.Println("fly!")
}
func main() {
    var i I
    i = A{}  // dynamic type of i is A
    fmt.Printf("%T\n", i.(A))
    // i.fly()  // 报错:./prog.go:26:6: i.fly undefined (type I has no field or method fly)
    var j J
    j = i.(J) // 这里将i中的值转换成接口J这一个类型
    fmt.Printf("%T\n", j)
    j.fly()
}

Output:

代码语言:javascript
复制
main.A
main.A
fly!

代码分析:

从上面的执行输出,我们可以看出来,接口i不能够调用fly()函数,尽管是用A{}来进行的赋值操作。接口j可以通过i来进行转换,此时j.fly()就可以被使用了。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 灰子学技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
腾讯云代码分析
腾讯云代码分析(内部代号CodeDog)是集众多代码分析工具的云原生、分布式、高性能的代码综合分析跟踪管理平台,其主要功能是持续跟踪分析代码,观测项目代码质量,支撑团队传承代码文化。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档