Golang 类型转换的实现(断言、强制、显式类型)

 更新时间:2023年09月03日 09:27:32   作者:动态一时爽,重构火葬场  
将一个值从一种类型转换到另一种类型,便发生了类型转换,在go可以分为断言、强制、显式类型转换,本文就详细的介绍一下这就几种转换方式,具有一定的参考价值,感兴趣的可以了解一下

将一个值从一种类型转换到另一种类型,便发生了类型转换。静态语言如c/c++,Java提供了隐性的类型转换,但对于golang这种强类型系统则不一样,golang并不支持自动类型转换或者隐性类型转换。

在go可以分为断言、强制、显式类型转换。

通常说的类型转换是指断言,强制一般不会用到,显式是基本的类型转换

断言

断言通过判断接口x是否不是nil且为T类型

var s = x.(T)

具体而言,在T不为接口时,要求x的动态类型就是T,并且T必须实现了x接口;否则类型断言无效,因为x不可能储存类型T的值

动态类型:接口类型可以包含对实现接口的任何类型的实例的引用(接口具有所谓的动态类型)

type I interface{ F() }
type S struct{}
func (S) F() { }
type T struct{}
func (T) F() { }
// 此时静态类型为接口I
var x I
// 此时动态类型为结构体S
x = S{}
// 重赋予x动态类型为结构体T
x = T{}

在T为接口时,x必须实现接口T

断言失败会触发panic,当然也可以s,ok:=x.(T),使用ok表示是否成功。

// 接口x转换为非接口类型	
	var x interface{} = 1
	y:=x.(int)
// 接口x转换为接口类型
type TypeAssertA interface {
	typeAssertA()
}
type TypeAssertB interface {
	typeAssertB()
}
type ta struct {}
func (t ta) typeAssertA() {}
func (t ta) typeAssertB() {}
// ta结构既实现了TypeAssertA又实现TypeAssertB,因此可以在两种接口类型之间相互转换
	var x TypeAssertA = ta{}
	y:=x.(TypeAssertB)

switch断言

switch判断具体值类型,而在case中匹配具体类型。也可以i:=x.(type)直接得到匹配类型的值

强制

通过unsafe等进行强制类型转换

比如将floag64类型转换为uint64类型,可能值表现不同,但内存二进制储存却是一样的

var f float64
u:= *(*uint64)(unsafe.Pointer(&f))

还可以用来进行接口类型检测

// 检查contextImpl是否实现了context接口
var c Context=(*ContextImpl)(nil)

显式

将一个类型表达式转换为另一个

var s =T(x)

在碰到*<-或者func开头的,最好使用括号以防止误用

*Point(p)        // same as *(Point(p))
(*Point)(p)      // p is converted to *Point
<-chan int(c)    // same as <-(chan int(c))
(<-chan int)(c)  // c is converted to <-chan int
func()(x)        // function signature func() x
(func())(x)      // x is converted to func()
(func() int)(x)  // x is converted to func() int
func() int(x)    // x is converted to func() int (unambiguous)

一个非常量x可以在以下情况下转换为类型T

  • x可以赋值为T
  • 忽略struct标签,x类型与T具有相同的基础类型
  • 忽略 struct 标记 x 的类型和 T 是未定义类型的指针类型,并且它们的指针基类型具有相同的基础类型。
  • x 的类型和 T 都是整数或浮点类型。
  • x 的类型和 T 都是复数类型。
  • x 的类型是整数或 [] byte 或 [] rune,并且 T 是字符串类型。
    或者x 的类型是字符串,T 类型是 [] byte 或 [] rune。

注意可以赋值为指的是(V为x类型):

  • V等于T
  • V和T是具有相同元素类型的通道类型,V是双向channel,且V或T中至少有一个不是以type命名的类型。
  • T是接口类型,但不是类型参数,x实现了T。
  • x是预先声明的标识符nil, T是指针、函数、切片、映射、通道或接口类型,但不是类型参数。
  • x是一个没有类型的常量,可以用类型T的值表示。

此外,如果x的类型V或T是类型参数,则在下列条件之一适用时,x可赋值给类型T的变量:

  • x是预先声明的标识符nil, T是一个类型参数,x可以赋值给T的类型集中的每个类型。
  • V不是一个命名类型,T是一个类型参数,x可以赋值给T的类型集中的每个类型。
  • V是一个类型参数,T不是一个命名类型,V的类型集中的每个类型的值都可以赋值给T。

Ref

 到此这篇关于Golang 类型转换的实现(断言、强制、显式类型)的文章就介绍到这了,更多相关Golang 类型转换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • GoLang与Java各自生成grpc代码流程介绍

    GoLang与Java各自生成grpc代码流程介绍

    这篇文章主要介绍了GoLang与Java各自生成grpc代码流程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2023-03-03
  • 详解Go 语言如何通过测试保证质量

    详解Go 语言如何通过测试保证质量

    这篇文章主要为大家介绍了Go 语言如何通过测试保证质量详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • go语言中for range使用方法及避坑指南

    go语言中for range使用方法及避坑指南

    Go中的for range组合可以和方便的实现对一个数组或切片进行遍历,但是在某些情况下使用for range时很可能就会被"坑",下面这篇文章主要给大家介绍了关于go语言中for range使用方法及避坑指南的相关资料,需要的朋友可以参考下
    2022-09-09
  • go值赋值和引用赋值的使用

    go值赋值和引用赋值的使用

    本文将介绍Go语言中的值赋值和引用赋值,并比较它们之间的差异,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-10-10
  • Go日志管理库zap安装及使用过程

    Go日志管理库zap安装及使用过程

    Zap是Go语言中一个高性能的日志记录库,它支持日志切割、多级别日志记录等功能,zap还支持使用Lumberjack进行日志文件的自动切割和归档,适用于需要高效日志管理的Go项目开发,本文介绍Go日志管理库zap安装及使用过程,感兴趣的朋友一起看看吧
    2024-09-09
  • golang中json小谈之字符串转浮点数的操作

    golang中json小谈之字符串转浮点数的操作

    这篇文章主要介绍了golang中json小谈之字符串转浮点数的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03
  • 一文带你了解Go中的内存对齐

    一文带你了解Go中的内存对齐

    一旦涉及到较为底层的编程,特别是与硬件交互,内存对齐是一个必修的课题,所以这篇文章小编就想来和大家聊一聊Go语言中的内存对齐,希望对大家有所帮助
    2023-10-10
  • Ubuntu安装Go语言运行环境

    Ubuntu安装Go语言运行环境

    由于最近偏爱Ubuntu,在加上作为一门开源语言,在Linux上从源代码开始搭建环境更让人觉得有趣味性。让我们直接先从Go语言的环境搭建开始
    2015-04-04
  • 详解Golang函数式选项(Functional Options)模式

    详解Golang函数式选项(Functional Options)模式

    什么是函数式选项模式,为什么要这么写,这个编程模式解决了什么问题呢?其实就是为了解决动态灵活的配置不同的参数的问题。下面通过本文给大家介绍Golang函数式选项(Functional Options)模式的问题,感兴趣的朋友一起看看吧
    2021-12-12
  • Go语言中错误处理实例分析

    Go语言中错误处理实例分析

    这篇文章主要介绍了Go语言中错误处理,实例分析了Go语言中针对错误处理的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02

最新评论