Go语言学习13-类型转换

2023-11-05

引言

在上一篇博文中,我们介绍了 Go 语言的 《数据的使用》;本篇博文,我们将介绍 Go 语言的类型转换

类型转换

1. 概念

类型转换是把一个类型的值转换成为另一个类型的值。把这个值原来的类型称为源类型,而这个值被转换后的类型称为目标类型

如果 T 是值 x 的目标类型,那么相应的类型转换表达式如下:

T(x) // x可以是一个表达式,不过这个表达式的结果值只能有一个

如果代表目标类型的字面量始于操作符 * 或 <- ,后者它是没有结果声明列表的函数类型,那么往往需要用圆括号括起来,以避免歧义的产生。例如:

*string(v)   // 等同于 *(string(v)),先将变量v代表的值转换为string类型的值,然后再获取指向它的指针类型值。
(*string)(v) // 把变量v的值转换为指针类型*string的值。

<-chan int(v)   // 等同于 <-(chan int(v)),先将变量v代表的值转换为chan int类型的值,然后再从此通道类型值中接收一个int类型的值。
(<-chan int)(v) // 把变量v的值转换为通道类型<-chan int的值。

func()(v)     // Go语言理解为任何无参数声明但有一个结果声明的匿名函数。
(func())(v)   // 把变量v的值转换为函数类型func()的值。
func() int(v) // 等同于(func() int)(v),把v的值转换成一个有结果声明的函数的类型。

对于常量 x,如果它能够被转换为类型 T 的值,那么它们符合如下情况:

  • x 可以被类型T的值代表。例如,iota 可以表示一个大于等于零的整数常量。他可以把 uint 类型的值代表。类型表达式 uint(iota) 是合法的,它的结果值会是一个 uint 类型的常量。

  • x 是一个浮点数常量,T 是一个浮点数类型,并且 x 在(根据IEEE-754标准中描述的向偶数舍入规则)被舍入之后可以被类型 T 的值代表。例如:

    float32(0.49999998) // 求值结果是一个float32类型的常量0.5
    
  • 如果 x 是一个整数常量,并且 T 是一个 string 类型,那么将会遵循一套规则来决定类型转换的结果。它同样适合于非常量的值。这将在后面的 与 string类型相关的转换 处讲解。

  • 对于非常量 x,它能够被转换为类型 T 的值,那么它们符合如下情况:
    x 可以被赋值给类型 T 的变量。例如:

    type Computer interface {
    	CpuType() string
    }
    
    type Laptop struct {
    	cpuType string
    }
    
    func (self Laptop) CpuType() string {
    	return self.cpuType
    }
    

    类型转换表达式:

    // 合法,求值结果会是一个Computer类型的值。因为类型Laptop是接口类型Computer的一个实现类型
    Computer(Laptop{cpuType: "Intel Core i5"}) 
    
  • x 的类型和类型 T 的潜在类型是相等的。例如:

    type MyString string
    // 类型转换表达式
    MyString("Huazie") // 合法,类型MyString的潜在类型就是string类型。
    
  • x 的类型和类型 T 都是未命名的指针类型,并且它们的基本类型(指向那个值的类型)的潜在类型是相等的。例如:

    var str1 string
    // 类型转换表达式
    (*string)(&str1) // 合法,求值结果是一个*MyString类型的值。
    
  • x 的类型和类型 T 都是整数类型或都是浮点数类型。例如:

    var i32 uint32
    var f32 folat32
    // 类型转换表达式
    int64(i32) // 合法。
    float64(f32) // 合法。
    
  • x 的类型和类型 T 都是复数类型。例如:

    var comp64 complex64
    // 类型转换表达式
    complex128(comp64) // 合法。
    
  • x 是一个整数类型值或是一个元素类型为 byterune 的切片类型值,且 T 是一个 string 类型。例如:

    string([]byte{'a'}) // 合法,求值结果是string类型值"a"。
    
  • x 是一个 string 类型值,且T是一个元素类型为 byterune 的切片类型。

    []rune("Huazie") // 合法
    

2. 数值类型之间的转换

可以通过常量声明或者数据类型转换把一个int类型的变量,数值常量1024无类型的,例如:

var number int = 1024

或把数值常量 1024 赋给一个 int 类型的变量:

int(1024)

对于非常量的数值类型值,规则如下:

  • 当把一个整数类型值从需要较少二进制位表示的整数类型转换到需要较多二进制位表示的整数类型(比如从 int8 类型转换到 int16 类型)的时候 : 如果这个整数类型值是有符号的,那么该符号位上的(最左边的)那个二进制值将作为扩展项填充在转换过程中新增的那些二进制位上,否则将会把 0 作为扩展项进行填充。这种扩展方式是针对整数类型值的补码而言的。例如:int16 类型值 -32767 的十六进制表示是 0xffff 。它的补码是 0x8001 。此补码最左边的二级制位上的二级制值是 1。如果要把这个 int16 类型值转换为 int32 类型值,就需要用最左边的这个值 1 填充在高位一侧新增的那16个二进制位上。类型转换之后的补码是 0xffff8001 。在这个补码之上再求其补码以得其原码,即 0x80007fff 。此原码表示的就是十进制数 -32767 ,类型转换前的那个数值相等。

  • 当把一个整数类型值从需要较多二级制位表示的整数类型转换到需要较少二级制位表示的整数类型的时候,需要把多余的若干个较高位置的二进制值裁掉,而只保留与目标类型所需二进制位数相当的若干个较低位置的二进制值。例如,int16 类型值 -32767,如果要把它转换为一个 int8 类型值,就需要对其补码 0x8001 截取较低 8 为的二进制值,得到 0x01。由于此值的最左边的二进制位上是 0,所以它本身就是类型转换总会得到一个有效的数值。但对于整数常量来说,这样的类型转换就会造成一个编译错误。例如,类型转换表达式 int8(-32767) 会使编译器报错,因为整数常量 -32767 超出了 int8 类型所能表示的数值范围。

  • 当把一个浮点数类型值向整数类型值进行转换的时候,该浮点数类型值的小数部分将被抹去。例如,如果有一个 float32 类型的变量 f32 且其值为 -32767.345 ,那么类型表达式 int32(f32) 的求值结果为 -32767 。如果浮点数类型值在被抹去小数位之后超出了目标整数类型的表示范围,那么该值还会被截短。例如,在类型表达式 int8(f32) 被求值的过程中会首先 float32 类型值 -32767.345 的小数部分却去掉,然后再将其中较高的 24 位的二进制值截掉,最终得到结果 1

  • 当把一个整数或浮点数转换为一个浮点数类型的值或者把一个复数转换为一个复数类型的值的时候,该值将会被依据目标类型的精度进行舍入操作。例如,在 float32 类型的变量 x 中存储的值可能会超出 IEEE-754 标准中规定的 32 位(二进制值代表的)浮点数的精度。但是,类型表达式 float32(x) 的求值结果一定会是 x 的值向32位浮点数的精度转化之后的值。算术表达式 x + 0.1 的结果值可能会超出32位浮点数的精度,但是类型转换表达式 float32(x + 0.1) 的求值结果却不会这样。

在非常量的浮点数类型值或复数类型值的类型转换中,当目标类型的精度不能够满足被转换的值的需要的时候,虽然转换会成功,但其结果将是不确定的,这依赖于不同平台的Go语言的具体实现。

3. 与string类型相关的转换

  • 当把一个有符号整数值或无符号整数值向字符串类型转换的时候,将会产生出一个字符串类型值。被转换的整数值应该是一个有效的 Unicode 代码点的代表。在作为结果的字符串类型值中的就是那个 Unicode 代码点对应的字符。在底层,这个字符串类型值是由该 Unicode 代码点的 UTF-8 编码值表示的。如果被转换的整数值不能代表一个有效的 Unicode 代码点,那么转换结果将会是**“\ufffd”**,即 Unicode 字符“�”。例如:

    string(0x4e2d) // 求值结果为“中”,其UTF-8编码为\xe4\xb8\xad
    string('国')   // 求值结果值为“国”,其UTF-8编码为\xe5\x9b\xbd
    string(-1)     // 求值结果为“�”,整数值-1不能代表一个有效的Unicode代码点。
    

    如果有一个目标类型是 string 类型的别名类型是 MyString,那么可以将它视同为 string 类型。例如:

    MyString(0x4e2d) // 等同于string(0x4e2d)
    
  • 当把一个元素类型为 byte 的切片类型值向字符串类型转换时,将会产生出一个字符串类型值。这个字符串类型值实际上就是由被转换的切片类型值中的每个字节类型值依次组合而成的。如果切片类型值为 nil,那么类型转换的结果将会是“”。例如:

    string([]byte{'g', '\x6f', '\x6c', '\x61', 'n', 'g'})//求值结果是"golang"
    

    由于使用 “\x” 为前导并后跟两位十六进制数可以表示宽度为一个字节的值,因此一个字节类型的值也就可以由这种方法表示。如果源类型是一个 [ ]byte 类型的别名类型,那么可以将它视同为 [ ]byte 类型。

  • 当把一个元素类型为 rune 的切片类型值向字符串类型转换时,将会产生出一个字符串类型值。这个字符串类型值实际上就是依次串联每个 rune 类型值后的结果。如果切片类型值为 nil,那么类型转换的结果将会是“”。例如:

    string([]rune{ 0x4e2D, 0x56fd })//求值结果是"中国"
    

    如果源类型是一个 [ ]rune 类型的别名类型,那么我们可以将它视同为 [ ]rune 类型。

  • 当把一个字符串类型值向 [ ]byte 类型转换时,其结果将会是把该字符串类型值按字节拆分后的结果。对于“”来说,转换后的结果一定是 [ ]byte 类型的空值 nil 。例如:

    []byte("hello")//结果是[]byte{104, 101, 108, 108, 111}
    

    在这个 [ ]byte 类型值中的每个元素都是对应字符的ASCII编码值的十进制表示形式。如果目标类型是一个 [ ]byte 类型的别名类型,那么可以将它视同为 [ ]byte 类型。

  • 当把一个字符串类型值向 [ ]rune 类型转换时,其结果将会是把该字符串类型值按字符拆分后的结果。对于 “” 来说,转换后的结果一定是 [ ]rune 类型的空值 nil

    []rune("中国") // 结果是[]byte{20013, 22269}
    

在这个 [ ]rune 类型值中的每个元素都是对应字符的 Unicode 代码点的十进制表示形式。如果目标类型是一个 [ ]rune 类型的别名类型,那么可以将它视同为 [ ]rune 类型。

UTF-8 这种编码方式会把一个字符编码为一个或多个字节。对于同一个字符串类型值来说,与它对应的字节序列和字符序列中的元素并不一定是一 一对应的。字节序列中的单个字节并不一定能代表一个完整的字符。例如,以字符串类型值“中国”为例:

// 字节序列的前三个元素代表了字符'中'的UTF-8编码值,而后三个元素则代表了字符'国'的UTF-8编码值。
[]byte{228, 184, 173, 229, 155, 189}
// 这个字符序列中的第一个元素代表了字符'中'的Unicode代码点,而第二个元素则代表了字符'国'的Unicode代码点。
[]byte{20013, 22269}

对于每一个ASCII编码可表示的字符来说,它的 Unicode 代码点和 UTF-8 编码值与其 ASCII 编码值都分别是一致的,且它们都可以由一个字节类型值代表。对于一个包含了 ASCII 编码可表示的字符的字符串类型值来说,与它对应的字节序列和字符序列中的元素值必定也是一一对应的。

byte 类型值和 rune 类型值都属于整数值的一种。所有整数值都可以由十进制字面量、八进制字面量和十六进制字面量来代表。可以把任意一种方式表示的 rune 字面量赋给任何整数类型的变量,只要该 rune 字面量对应的 Unicode 代码点不超出那个整数类型的表示范围。例如:

var nation int16 = '国' // '国' == 0x56fd == 22269
[]byte{ 'g', '\x6f', '0x6c', '\u0061', '\156', '\U00000067' } // 求值结果是"golang"

4. 别名类型值之间的转换

类型是 MyStringstring 类型的别名类型。如果一个整数值分别转换为这两个类型的值,将会得到相同的结果。把一个字符串字面量赋给 MyString 类型的变量:

var ms MyString = "中国"

MyString 类型的值之上应用切片操作:

ms[1]

在某个数据类型和它的别名类型之间以及同一个数据类型的多个别名类型之间的类型转换是合法的。并且,在这种类型转换的过程中并不会创造出新的值,而仅仅是变换了一下那个已存在的值的所属类型。

结语

本篇主要介绍了Go语言数据使用中类型转换相关的内容,下一篇我们将会介绍Go语言的一些内建函数的使用,敬请期待!!!

最后附上知名的Go语言开源框架:

etcd: 一个高可用的键值存储系统。它可被用于建立共享配置系统和服务发现系统。它的灵感来自于Apache ZooKeeper。我们可以在https://github.com/coreos/etcd上找到它的源码。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Go语言学习13-类型转换 的相关文章

  • JackSon Double类型转换为BigDecimal类型

    话不多说直接放代码 SimpleModule module new SimpleModule module addSerializer Double class new StdSerializer BigDecimal class Over
  • Go语言学习5-切片类型

    切片类型 引言 1 切片 1 1 类型表示法 1 2 值表示法 1 3 属性和基本操作 1 4 切片使用的复杂用法 总结 引言 上篇我们介绍了 Go语言的数组类型 本篇将介绍Go语言的切片类型 主要如下 1 切片 切片可以看作是对数组的一种
  • Go语言学习16-特殊流程控制

    特殊流程控制 引言 特殊流程控制 1 defer语句 2 异常处理 2 1 error 2 2 panic 2 3 recover 结语 引言 上一篇博文介绍了 Go 语言的基本流程控制 本篇我们介绍 Go 语言的特殊流程控制 特殊流程控制
  • Sublime Text 3配置Go语言开发环境

    Sublime Text 3配置Go语言开发环境 1 Go语言环境搭建 2 GoSublime安装和配置 2 1 安装步骤 2 2 代码开发 2 3 编译运行 1 Go语言环境搭建 本篇博文是在读者Go自身环境已经搭好 Sublime Te
  • 无符号16位整形数组转float---Java

    代码 public float int16tofloat int a if 0 a length 2 a length lt 0 return null int len a length 2 float c new float len fo
  • static_cast、dynamic_cast、const_cast和reinterpret_cast总结

    文章转载自 http www jellythink com archives 205 前言 这篇文章总结的是C 中的类型转换 这些小的知识点 有的时候 自己不是很注意 但是在实际开发中确实经常使用的 俗话说的好 不懂自己写的代码的程序员 不
  • 【深入理解C++】类型转换

    文章目录 1 隐式类型转换 2 显式类型转换 强制类型转换 2 1 C语言 2 2 C 语言 2 2 1 static cast 2 2 1 1 可用于 2 2 1 2 不可用于 2 2 2 dynamic cast 2 2 3 const
  • golang类型转换与类型断言

    类型转换在程序设计中都是不可避免的问题 当然有一些语言将这个过程给模糊了 大多数时候开发者并不需要去关注这方面的问题 但是golang中的类型匹配是很严格的 不同的类型之间通常需要手动转换 编译器不会代你去做这个事 我之所以说通常需要手动转
  • 基本数据类型强制转换问题-值的截断和内存的截断

    1 double a1 22 32 int b1 int a1 2 double a2 2 5e20 int b2 int a2 按照浮点数到整数的转换语义 结果应该截去浮点数的小数部分 而保留整数部分 所以b1应该为22 而b2则超出了其
  • 【C++ Primer】重载运算与类型转换

    文章目录 一 基本概念 二 输入输出运算符 1 重载输出运算符 lt lt 2 重载输入运算符 gt gt 三 算数和关系运算符 1 相等运算符 2 关系运算符 四 赋值运算符 五 下标运算符 六 递增递减运算符 七 成员访问运算符 八 函
  • Go语言学习15-基本流程控制

    基本流程控制 流程控制对比 Go 和 C 基本流程控制 1 代码块和作用域 2 if 语句 3 switch语句 3 1 表达式switch语句 3 2 类型switch语句 4 for 语句 4 1 for 子句 4 2 range 子句
  • C++中的内置类型以及类型转换

    在开始介绍类型转换之前 我们先了解一下C 中的数据类型 不太清楚的朋友可以先看下第一部分的介绍 1 C 中的内置类型 C 中的内置内型主要分为基本类型和复合类型 1 1基本类型 基本类型主要指整数和浮点数 而整数又可以分为short int
  • qt下QString转换为const char*字符串

    概述 本文直在说明将QString类型的变量转换为const char 类型 实现 可以采用下面的方式来实现 QString toStdString c str 示例 下面是一个示例 const QString msg nis你好 cons
  • org.springframework.validation.BindException: org.springframework.

    错误信息 org springframework validation BindException org springframework validation BeanPropertyBindingResult 2 errors Fiel
  • java各类型String,int,char,long,StringBuilder,StringBuffer,Integer之间的转换总结

    String和char类型之间的转换 1 String char 因为String是字符串 而char是单个字符 只能把String 转化为char数组 方法为 char ch str toCharArray 2 char String 方
  • C、C++、Qt类型转换总结

    一 C类型转换 转换格式如下 Type b Type a 二 C 类型转换 1 const cast 去掉类型的const或volatile属性 const int a 10 a 20 compile error int b const c
  • Go语言学习9-结构体类型

    结构体类型 引言 1 结构体 1 1 类型表示法 1 2 值表示法 1 3 属性和基本操作 附录 引言 书接上篇 我们了解了Go语言的接口类型 现在介绍Go语言的结构体类型 主要如下 1 结构体 结构体类型既可以包含若干个命名元素 又称字段
  • 工作——自动化测试中用到的SQL server查询语句的格式调整

    SELECT CONVERT VARCHAR 100 GETDATE 0 05 16 2006 10 57AM SELECT CONVERT VARCHAR 100 GETDATE 1 05 16 06 SELECT CONVERT VAR
  • 【Java数据类型】各种数据类型的相互转换总结

    基础数据类型包括 byte short int long float double char String boolean 在许多场合需要用到它们的相互转换 本文 将介绍几种转换方式 以及对转换方式的原理简要介绍 文章目录 法则与特性 字节
  • Go语言学习4-数组类型

    数组类型 引言 1 数组 1 1 类型表示法 1 2 值表示法 1 3 属性和基本操作 总结 引言 上篇我们了解 Go语言的基本数据类型 现在开始介绍数组类型 主要如下 1 数组 在Go语言中 数组被称为Array 就是一个由若干相同类型的

随机推荐

  • vue.js关于动态绑定数据

    最近在写vue的时候发现一个问题 在后台传过来的一个数组需要给页面进行渲染 需要为每个 li 标签吧绑定一个点击事件 这个点击事件需要取这个 li li 标签的name属性的值 然后再进行页面的跳转 如何给name赋值呢 刚开始如上图写的
  • vue+element+el-table表格简单封装成组件

    封装后调用 我的页面是这样的 像那些图片 按钮 和状态这些 都是埋好的具名插槽 配置的时候先传插槽的名字 然后在table组件中对应名字 就形成了 具体看代码 比较详细 直接复制引用就可以展示 我在props里定义了点默认值 引用时方便理解
  • FPGA常用通信协议之IIC

    目录 1 概述 2 IIC时序 2 1数据位的有效性规定 2 2起始 终止 应答 非应答信号 2 3数据传送格式 2 4总线的寻址 3 FPGA读写EEPROM 3 1EEPROM芯片手册 3 1 1写时序 3 1 2读时序 3 1 3硬件
  • CSliderCtrl::ClearSel

    CSliderCtrl ClearSel void ClearSel BOOL bRedraw FALSE Parameters bRedraw Redraw flag If this parameter is TRUE the slide
  • 2022年的vue、react面试题目汇总集合(持续更新)

    vue系列 2021 Vue js 面试题汇总及答案 Jack Niu 博客园 react系列 React面试题及答案 2021年React面试题大全带答案 知乎 2021年React常见的面试题以及答案 持续更新中 再见已是路人的博客 C
  • 图像边缘检测及其在MATLAB中的实现

    图像边缘检测及其在MATLAB中的实现 图像边缘检测是数字图像处理中的常用技术之一 它可以帮助我们识别出物体的轮廓 形状等特征 下面介绍几种常用的边缘检测方法以及在MATLAB中的实现方法 Roberts算子 Roberts算子又称Prew
  • abaqus6.14导出网格inp以及导入inp以建模

    建好part 组装后 划分网格 然后建立job 之后write input就可以在工作目录生成刚才新建网格的单元和节点编号信息了 1 Heading 2 Job name buildmodel Model name Model 1 3 Ge
  • Expected more than 1 value per channel when training, got input size torch.Size

    Expected more than 1 value per channel when training got input size torch Size 训练的时候 batch size必须大于1 但是预测的时候 batch size可
  • 阿白数模笔记之遗传算法(genetic algorithm)MATLAB代码详解

    目录 Preface 一 极值问题Extremum problem 1 参数初始化 Parameter initialization 2 解码 decode 3 轮盘赌 选择淘汰Roulette choose to eliminate 4
  • 多维时序

    多维时序 Matlab实现BiLSTM Adaboost和BiLSTM多变量时间序列预测对比 目录 多维时序 Matlab实现BiLSTM Adaboost和BiLSTM多变量时间序列预测对比 预测效果 基本介绍 模型描述 程序设计 参考资
  • numpy的loadtxt遇到问题:ValueError: Wrong number of columns at line 2 原因调查

    在使用python做验证码识别的过程中 在调用numpy的loadtxt函数时发生如下错误 Traceback most recent call last File D My Documents test jpg ok py line 36
  • 【Docker】Docker使用之容器技术发展史

    博客主页 博主链接 本文由 M malloc 原创 首发于 CSDN 学习专栏推荐 LeetCode刷题集 欢迎点赞 收藏 留言 如有错误敬请指正 未来很长 值得我们全力奔赴更美好的生活 文章目录 本章详情 Jail时代 1979 年 贝尔
  • 华为OD机试题:消除相邻且相同

    题目描述 输入一个只包含英文字母的字符串 字符串中的俩个字母如果相邻且相同 就可以消除 在字符串上反复执行消除的动作 直到无法继续消除为止 此时游戏结束 输出最终得到的字符串长度 输入描述 原始字符串只能包含大小写英文字母 字母的大小写敏感
  • 禁止系统运行某个进程的简单方法(注册表操作)

    一 解决方法 修改注册表 HKLM SOFTWARE Microsoft Windows NT CurrentVersion Image File Execution Options 下建立一个以要禁用的程序名命名的子项 如 hudan e
  • python爬虫修饰_python爬虫URL重试机制的实现方法(python2.7以及python3.5)

    应用场景 状态不是200的URL重试多次 代码比较简单还有部分注释 python2 7实现 coding utf 8 ayou import requests def url retry url num retries 3 print ac
  • 生活中那些六 “有” 的人

    1 有承诺 一些事情开始的时候总会有些协议与约定 我们称其为承诺 我们必须遵守承诺 即使是约会也要遵守 也不能迟到 迟到这件事不但会妨碍我们所有人 还意味着迟到者不尊重大家的时间 这种约定从某种意义上来讲也是承诺 如果你来晚了 这就表示你的
  • 蓝桥杯考生规则

    2017年模拟赛 本科组 考生须知 l 考试开始后 选手首先下载题目 并使用考场现场公布的解压密码解压试题 l 考试时间为4小时 时间截止后 提交答案无效 l 在考试强制结束前 选手可以主动结束考试 需要身份验证 结束考试后将无法继续提交或
  • java计算机毕业设计火车订票系统源码+mysql数据库+系统+lw文档+部署

    java计算机毕业设计火车订票系统源码 mysql数据库 系统 lw文档 部署 java计算机毕业设计火车订票系统源码 mysql数据库 系统 lw文档 部署 本源码技术栈 项目架构 B S架构 开发语言 Java语言 开发软件 idea
  • Tomcat调优

    问题定位 对于Tomcat的处理耗时较长的问题主要有当时的并发量 session数 内存及内存的回收等几个方面造成的 出现问题之后就要进行分析了 1 关于Tomcat的session数目 这个可以直接从Tomcat的web管理界面去查看即可
  • Go语言学习13-类型转换

    类型转换 引言 类型转换 1 概念 2 数值类型之间的转换 3 与string类型相关的转换 4 别名类型值之间的转换 结语 引言 在上一篇博文中 我们介绍了 Go 语言的 数据的使用 本篇博文 我们将介绍 Go 语言的类型转换 类型转换