类型转换在编程语言中是很常见的操作,在 Go 语言中其类型转换有下面一些注意点。

1. 整数类型之间的转换

对于整数类型转换,原则上目标类型的取值范围要包含被转换值,也就是说要转换类型的值取值范围要小于目标类型的取值范围。

如果相反,即目标类型小,而要转换的源值类型大,比如把值的类型从 int16 转换为 int8 ,会出现截断现象,如下代码:

func main() {src := int16(-255)dst := int8(src)fmt.Println("dst is ", dst) // dst is  1
}

变量 src 的值是 int16 类型的 -255 ,而变量 dst 的值是由前者转换而来的,类型是 int8int16 类型的可表示范围可比 int8 类型大。

整数在计算机中都是以补码的形式存储的。其中:

  • 正数补码和原码相同;
  • 负数补码是原码各位求反再加 1;

比如,int16 类型的值 -255 的补码是 1111111100000001

该值在转换为 int8 类型的值,那么就会把在较高位置(或者说最左边位置)上的 8 位二进制数直接截掉,从而得到 00000001 。又由于其最左边一位是 0 ,表示它是个正整数,以及正整数的补码就等于其原码,所以 dst 的值就是 1 。

规则:

  1. 当整数值的类型的有效范围由宽变窄时,只需在补码形式下截掉一定数量的高位二进制数即可;
  2. 当浮点数类型的值转换为整数类型值时,会把浮点数值的小数部分全部截掉;

2. 整数转换字符串

把整数转换为字符串,有两种方法可以使用,分别是:

  • 使用 string 直接转换;
  • 使用 strconv 库方法进行转换;

两者的区别,可以看下面代码:

func main() {a := 101s1 := string(a)s2 := strconv.Itoa(a)fmt.Printf("s1 is %#v, type is %T\n", s1, s1)fmt.Printf("s2 is %#v, type is %T\n", s2, s2)
}

输出结果:

s1 is "e", type is string
s2 is "101", type is string

我们可以看到区别,

  • string 方法是将整数转换为对应的 ASCII/Unicode 码值;
  • strconv 库的 Itoa 方法是将整数转换成整数字面量对应的字符串;

如下代码也是同样的

func main() {a := 0x597Ds1 := string(a)s2 := strconv.Itoa(a)fmt.Printf("s1 is %#v, type is %T\n", s1, s1)fmt.Printf("s2 is %#v, type is %T\n", s2, s2)
}

输出结果:

s1 is "好", type is string
s2 is "22909", type is string

16 进制数 0x597D 的十进制数字为 22909 ,且其 Unicode 值为汉字的

但需要关注的是,被转换的整数值应该可以代表一个有效的 Unicode 代码点,否则转换的结果将会是 (仅由高亮的问号组成的字符串值)。

func main() {a := -2s1 := string(a)s2 := strconv.Itoa(a)fmt.Printf("s1 is %#v, type is %T\n", s1, s1)fmt.Printf("s2 is %#v, type is %T\n", s2, s2)
}

输出结果为

s1 is "�", type is string
s2 is "-2", type is string

由于 -2 无法代表一个有效的 Unicode 值,所以得到的总会是

3. string类型与各切片类型之间转换

一个值在从 string 类型向 []byte 类型转换时,除了与 ASCII 编码兼容的那部分字符集可以用单个字节表示之外,以 UTF-8 编码的字符串会被拆分成零散、独立的字节,单一字节是无法代表一个字符的。

func main() {a := "你好"s1 := string(a)s2 := []byte(a)s3 := []rune(a)fmt.Printf("s1 is %#v, type is %T\n", s1, s1)fmt.Printf("s2 is %#v, type is %T\n", s2, s2)fmt.Printf("s3 is %#v, type is %T\n", s3, s3)
}

输出结果为:

s1 is "你好", type is string
s2 is []byte{0xe4, 0xbd, 0xa0, 0xe5, 0xa5, 0xbd}, type is []uint8
s3 is []int32{20320, 22909}, type is []int32

0xe4, 0xbd, 0xa0 合在一起才能代表字符 ,而 0xe5 , 0xa5 , 0xbd 合在一起才能代表符

一个值在从 string 类型向 []rune 类型转换时代表着字符串会被拆分成一个个 Unicode 字符。

[]int32{20320, 22909} // 你好

4. 类型转换三方库

第三方包 github.com/spf13/cast 专门解决类型转换的问。这个包使用很简单,主要有两套函数:

  1. To_ 形式函数

这些函数始终返回所需的类型。如果无法正确转换为对应的类型,则返回目标类型的零值。

支持的类型包括所有的基本数据类型,还支持 time.Timetime.Durationslicemap 等常用类型。

比如:

cast.ToString("mayonegg")         // "mayonegg"
cast.ToString(8)                  // "8"
cast.ToString(8.31)               // "8.31"
cast.ToString([]byte("one time")) // "one time"
cast.ToString(nil)                // ""
cast.ToTime("2021-08-10 22:00:00") // 2021-08-10 22:00:00 +0000 UTC

注意,转换为 time.Time 时,需要注意时区问题。ToTime 默认使用 UTC,如果想用其他时区,得类似这么做:

secondsEastOfUTC := int((8 * time.Hour).Seconds())
beijing := time.FixedZone("Beijing Time", secondsEastOfUTC)
fmt.Println(cast.ToTimeInDefaultLocation("2021-08-10 22:00:00", beijing))

当然,你也可以这样:

fmt.Println(cast.ToTimeInDefaultLocation("2021-08-10 22:00:00", time.Local))

不过,Local 表示本地时区,要明确这个本地是不是你想要的。

  1. To_E 形式函数

E 表示 error,也就是说,这一系列函数会返回 error。在无法进行类型转换时,会将错误原因返回。To_ 形式内部调用的是 To_E 形似,只是它忽略了错误。

这种形式就不举例了。一般地,除非你需要区分零值是因为出错导致的还是本身就是零值,否则应该使用 To_ 系列函数,毕竟更省事。

Go 知识点(12) — 类型转换以三方库 cast相关推荐

  1. Android解析JSON,你真的需要三方库?

    一般情况下,如果服务器返回 JSON 数据,而且你又是做 Android 的,那么你首先想到的可能是GSON,或是fastJson这样的框架.这些框架能够很方便和快速的让我们将 JSON 转换成本地对 ...

  2. python安装第三方库win10_音频处理 windows10下python三方库librosa安装教程

    librosa是处理音频库里的opencv,使用python脚本研究音频,先安装三方库librosa. 如下通过清华镜像源安装librosa: pip install -i https://pypi. ...

  3. iOS最全的三方库、插件、博客汇总

    目录 UI@ 日历三方库@ 下拉刷新@ 模糊效果@ 富文本@ 图表@ 颜色@ 表相关@(TabbleView.Tabbar.即时聊天界面) TableView@ CollectionView@ 隐藏与 ...

  4. python安装第三方库re_音频处理 windows10下python三方库librosa安装教程

    librosa是处理音频库里的opencv,使用python脚本研究音频,先安装三方库librosa. 如下通过清华镜像源安装librosa: pip install -i https://pypi. ...

  5. 音频处理 windows10下python三方库librosa安装

    librosa是处理音频库里的opencv,使用python脚本研究音频,先安装三方库librosa. 如下通过清华镜像源安装librosa: pip install -i https://pypi. ...

  6. Android ShapeableImageView使用详解,告别shape、三方库

    效果 前言 先来看一下ShapeableImageView是什么 由上图可以看到ShapeableImageView也没有什么神秘的,不过是ImageView的一个子类而已,但是从效果图来看,在不写s ...

  7. 三方库源码学习2-Retrofit

    文章目录 一.参考博客 二.Retrofit的介绍 三.什么是动态代理 四. Retrofit.Create()方法 五. ServiceMethod 六. 初看HttpServiceMethod 七 ...

  8. 推荐收藏,Python 量化金融三方库收集(100+)

    大家好,今天给大家汇总了定量金融的大量三方库,按功能进行分类,覆盖数值运算,衍生品定价,回溯检验,风险管理,数据爬取,可视化等多个子领域,供每个 Python 程序员参考.喜欢记得收藏.关注.点赞. ...

  9. 乾坤大挪移,如何将同步阻塞(sync)三方库包转换为异步非阻塞(async)模式?Python3.10实现。

    众所周知,异步并发编程可以帮助程序更好地处理阻塞操作,比如网络 IO 操作或文件 IO 操作,避免因等待这些操作完成而导致程序卡住的情况.云存储文件传输场景正好包含网络 IO 操作和文件 IO 操作, ...

最新文章

  1. python打开文件_喜大普奔 | 如何在Win10下利用Python打开grib文件
  2. 【IT笔试面试题整理】堆栈和队列
  3. android 文件 c语言 jni,Android jni 调用的so文件一个函数的反汇编 高手来看看
  4. 数据库如何进行索引优化
  5. 牛客16732 序列(排列组合)
  6. 三菱goto怎么用_GOTO语句使用方法
  7. 不懂技术的产品经理,真的是“祸害人类”吗?
  8. Python uuid 学习总结
  9. 6月首批国产游戏获批:共55款 腾讯B站上榜
  10. 使用oracle sql profile固定执行计划
  11. Python常用运算符含义与用法演示
  12. java gc回收算法_Java基础之GC垃圾回收的历史
  13. GraphQL从入门到实战
  14. 2021-08-09 idea -- Mysql 增删改查
  15. 新宝线上股票大箱体终于向上突破站稳了
  16. CPP 获取目录下的文件
  17. opencore 0.6.3 华硕_钜惠嗨翻双11,颜值优选华硕GT501白色狙击手机箱
  18. ANC主动降噪的量化描述
  19. [Tips]Ubuntu20.04域名解析失败或网速很慢
  20. 推荐两款好用的企业级内网穿透软件

热门文章

  1. stream流对象的理解及使用
  2. 基于Golang的监听读取配置文件的程序包开发——simpleConfig_v1
  3. 2022-2028年中国PET薄膜行业市场深度分析及未来趋势预测报告
  4. SpringCloud配置文件 application.yml和 bootstrap.yml区别,执行顺序
  5. PyTorch里面的torch.nn.Parameter()
  6. LeetCode简单题之将句子排序
  7. 如何在CPU上优化GEMM(上)
  8. 管道:介绍和基本服务
  9. 2019个嵌入式市场研究,持续的C/C++优势
  10. 2021年大数据常用语言Scala(十七):基础语法学习 Set