1.  
  2. 主页
  3.  / 
  4. Go 每日一库
  5.  / 
  6. Go 每日一库之 cast 使用详解

Go 每日一库之 cast 使用详解

简介

今天我们再来介绍 spf13 大神的另一个库cast

cast是一个小巧、实用的类型转换库,用于将一个类型转为另一个类型。

最初开发cast是用在hugo中的。

快速使用

先安装:

后使用:

实际上,cast实现了多种常见类型之间的相互转换,返回最符合直觉的结果。例如:

  • nil转为string的结果为"",而不是"nil"
  • true转为string的结果为"true",而true转为int的结果为1
  • interface{}转为其他类型,要看它里面存储的值类型。

这些类型包括所有的基本类型(整形、浮点型、布尔值和字符串)、空接口、nil,时间(time.Time)、时长(time.Duration)以及它们的切片类型,还有map[string]Type(其中Type为前面提到的类型):

高级转换

cast提供了两组函数:

  • ToType(其中Type可以为任何支持的类型),将参数转换为Type类型。如果无法转换,返回Type类型的零值或nil
  • ToTypeE以 E 结尾,返回转换后的值和一个error。这组函数可以区分参数中实际存储了零值,还是转换失败了。

实现上大部分代码都类似,ToType在内部调用ToTypeE函数,返回结果并忽略错误。ToType函数的实现在文件cast.go中,而ToTypeE函数的实现在文件caste.go中。

ToTypeE函数都接受任意类型的参数(interface{}),然后使用类型断言根据具体的类型来执行不同的转换。

如果无法转换,返回错误。

首先调用indirect函数将参数中可能的指针去掉。如果类型本身不是指针,那么直接返回。

否则返回指针指向的值。

循环直到返回一个非指针的值:

所以,下面代码输出都是 8:

时间和时长转换

时间类型的转换代码如下:

根据传入的类型执行不同的处理:

  • 如果是time.Time,直接返回;
  • 如果是整型,将参数作为时间戳(自 UTC 时间1970.01.01 00:00:00到现在的秒数)调用time.Unix生成时间。Unix接受两个参数,第一个参数指定秒,第二个参数指定纳秒;
  • 如果是字符串,调用StringToDate函数依次尝试以下面这些时间格式调用time.Parse解析该字符串。如果某个格式解析成功,则返回获得的time.Time。否则解析失败,返回错误;
  • 其他任何类型都无法转换为time.Time

字符串转换为时间:

时长类型的转换代码如下:

根据传入的类型进行不同的处理:

  • 如果是time.Duration类型,直接返回;
  • 如果是整型或浮点型,将其数值强制转换为time.Duration类型,单位默认为ns
  • 如果是字符串,分为两种情况:如果字符串中有时间单位符号nsuµmh,直接调用time.ParseDuration解析;否则在字符串后拼接ns再调用time.ParseDuration解析;
  • 其他类型解析失败。

示例:

转换为切片

实际上,这些函数的实现基本类似。使用类型断言判断类型。如果就是要返回的类型,直接返回。否则根据类型进行相应的转换。

我们主要分析两个实现:ToIntSliceEToStringSliceEToBoolSliceE/ToDurationSliceEToIntSliceE基本相同。

首先是ToIntSliceE

根据传入参数的类型:

  • 如果是nil,直接返回错误;
  • 如果是[]int,不用转换,直接返回;
  • 如果传入类型为切片数组,新建一个[]int,将切片或数组中的每个元素转为int放到该[]int中。最后返回这个[]int
  • 其他情况,不能转换。

ToStringSliceE

根据传入的参数类型:

  • 如果是[]interface{},将该参数中每个元素转为string,返回结果切片;
  • 如果是[]string,不需要转换,直接返回;
  • 如果是interface{},将参数转为string,返回只包含这个值的切片;
  • 如果是string,调用strings.Fields函数按空白符将参数拆分,返回拆分后的字符串切片;
  • 其他情况,不能转换。

示例:

转为map[string]Type类型

cast库能将传入的参数转为map[string]Type类型,Type为上面支持的类型。

其实只需要分析一个ToStringMapStringE函数就可以了,其他的实现基本一样。

ToStringMapStringE返回map[string]string类型的值。

根据传入的参数类型:

  • 如果是map[string]string,不用转换,直接返回;
  • 如果是map[string]interface{},将每个值转为string存入新的 map,最后返回新的 map;
  • 如果是map[interface{}]string,将每个键转为string存入新的 map,最后返回新的 map;
  • 如果是map[interface{}]interface{},将每个键和值都转为string存入新的 map,最后返回新的 map;
  • 如果是string类型,cast将它看成一个 JSON 串,解析这个 JSON 到map[string]string,然后返回结果
  • 其他情况,返回错误。

示例:

总结

cast库能在几乎所有常见类型之间转换,使用非常方便。代码量也很小,有时间建议读读源码。

完整示例代码在GitHub上。

参考

  1. cast GitHub 仓库
这篇文章对您有用吗?

我们要如何帮助您?

发表评论

邮箱地址不会被公开。 必填项已用*标注