由于Go语言不存在隐式类型转换,因此所有的类型转换都必须显式的声明。
string、int、float类型相互转换
string转其他
- string转成int:
int, err := strconv.Atoi(string)
- string转成int64:
// 参数1:带转换字符串,
// 参数2:基于几进制,值可以是0,8,16,32,64
// 参数3:要转成哪个int类型:可以是0、8、16、32、64,分别对应 int,int8,int16,int32,int64
int64, err := strconv.ParseInt(string, 10, 64)
- string转成uint64:
uint64, err := strconv.ParseUint(string, 10, 64)
- string转成float64、float32
// ParseFloat 将字符串转换为浮点数
// str:要转换的字符串
// bitSize:指定浮点类型(32:float32、64:float64)
// 如果 str 是合法的格式,而且接近一个浮点值,
// 则返回浮点数的四舍五入值(依据 IEEE754 的四舍五入标准)
// 如果 str 不是合法的格式,则返回“语法错误”
// 如果转换结果超出 bitSize 范围,则返回“超出范围”
//到float64
float64,err := strconv.ParseFloat(str,64)
//到float32
float32,err := strconv.ParseFloat(str,32)
int、int64、uint64转其他
- int转成string:
string := strconv.Itoa(int)
// 或者:先把int转为int64
string := strconv.FormatInt(int64(int), 10)
- int64转成string:
string := strconv.FormatInt(int64,10)
- uint64转成string:
string := strconv.FormatUint(uint64,10)
- int转float32
float := float32(int)
float转其他
- float转成string
// FormatFloat 将浮点数 f 转换为字符串值
// f:要转换的浮点数
// fmt:格式标记(b、e、E、f、g、G)
// prec:精度(数字部分的长度,不包括指数部分)
// bitSize:指定浮点类型(32:float32、64:float64)
// 格式标记:
// 'b' (-ddddp±ddd,二进制指数)
// 'e' (-d.dddde±dd,十进制指数)
// 'E' (-d.ddddE±dd,十进制指数)
// 'f' (-ddd.dddd,没有指数)
// 'g' ('e':大指数,'f':其它情况)
// 'G' ('E':大指数,'f':其它情况)
// 如果格式标记为 'e','E'和'f',则 prec 表示小数点后的数字位数
// 如果格式标记为 'g','G',则 prec 表示总的数字位数(整数部分+小数部分)
str1 = strconv.FormatFloat(11.34,'E',-1,32)
str2 = strconv.FormatFloat(10.55,'E',-1,64)
fmt.Println(str1,str2) //1.134E+01 1.055E+01
//解析转换后的string变量str为float
h,_ :=strconv.ParseFloat(str1,32)
fmt.Println(h) //11.34000015258789
h,_ =strconv.ParseFloat(str2,64)
fmt.Println(h) //10.55
- float转int64(会有精度损失)
var x float64 = 6.9
y := int64(x)
类型断言
- 类型断言的本质,跟类型转换类似,都是类型之间进行转换,不同之处在于,类型断言是在接口之间进行。类型转换在编译期完成,类型断言在运行时确定,包括安全类型断言和非安全类型断言。
- 语法:
<目标类型的值>,<布尔参数> := <表达式>.( 目标类型 ) // 安全类型断言
<目标类型的值> := <表达式>.( 目标类型 ) //非安全类型断言
var a interface{}
value, ok := a.(string)
if !ok {
fmt.Println("It's not ok for type string")
return
}
fmt.Println("The value is ", value)
- 可以配合switch语句进行判断
var t interface{}
t = functionOfSomeType()
switch t := t.(type) {
case bool:
fmt.Printf("boolean %t\n", t) // t has type bool
case int:
fmt.Printf("integer %d\n", t) // t has type int
case *bool:
fmt.Printf("pointer to boolean %t\n", *t) // t has type *bool
case *int:
fmt.Printf("pointer to integer %d\n", *t) // t has type *int
}
default:
fmt.Printf("unexpected type %T", t) // %T prints whatever type t has
时间与时间戳
时间类型
获取当地时间,获取时间的函数为time.now(),这里加不加.Local(),获取的都是当地时间。加.UTC得到的是0时区(也就是伦敦)的时间。func Now() Time这个函数的返回值是Time,也就是时间类型。例如:
fmt.Println(time.Now())
fmt.Println(time.Now().Local())
fmt.Println(time.Now().UTC())
fmt.Println(time.Now().Location())
// 输出
2018-11-21 11:50:39.540473 +0800 CST m=+0.000311562
2018-11-21 11:50:39.540628 +0800 CST
2018-11-21 03:50:39.540632 +0000 UTC
Local
时间戳
时间戳函数的返回值都是int64,是一个大整数。时间戳就是格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起到此时此刻的【总秒数】。
fmt.Println(time.Now().Unix())
fmt.Println(time.Now().Local().Unix())
fmt.Println(time.Now().UTC().Unix())
fmt.Println(time.Now().UnixNano())
// 输出
1542772752
1542772752
1542772752
1542772752846107000
在go语言中,time.Now().Unix()或者time.Now().Local().Unix()就是【北京时间1970年01月01日08时00分00秒】到【北京时间此时此刻】的总秒数。
相应的time.Now().UTC().Unix()就是【格林威治时间1970年01月01日00时00分00秒】到【格林威治时间此时此刻】的总秒数。因此上面得到的几个时间戳是一样的。时间戳是一个【总秒数】,所以时间戳函数的返回值都是int64。所以go语言中有时间类型,但并没有一个单独的【时间戳类型】。
时间类型格式化
将时间类型格式化,得到一个表示时间的字符串。第一行是time.Now()的结果,是时间类型【Time】下面两行是t.Format()的结果,是字符串。
t := time.Now()
str := t.Format("2006-01-02 15:04:05")
str1 := t.Format("2006年1月2日 15:04:05")
fmt.Println(t)
fmt.Println(str)
fmt.Println(str1)
// 输出
2018-11-21 12:48:19.870047 +0800 CST m=+0.000503740
2018-11-21 12:48:19
2018年11月21日 12:48:19
字符串转Time
函数func Parse(layout, value string) (Time, error)的第一个参数是需要转换的字符串的格式,第二个参数是需要转换的字符串。返回值是时间类型和一个err。
t := time.Now()
str := t.Format("2006-01-02 15:04:05")
str1 := t.Format("2006年1月2日 15:04:05")
timestamp, _ := time.Parse("2006-01-02 15:04:05", str)
timestamp1, _ := time.Parse("2006年1月2日 15:04:05", str1)
fmt.Println(timestamp)
fmt.Println(timestamp1)
// 输出
2018-11-21 12:48:19 +0000 UTC
2018-11-21 12:48:19 +0000 UTC
在将字符串转为时间类型的时候,是直接转为了【伦敦时间】,go语言并不会去判断这个字符串表示的是北京时间,还是伦敦时间,因为没法判断,只有你知道它表示的是哪里的时间。比如16:08:05在中国那当然表示的是北京时间,但是如果把这个字符串转为时间类型,就直接变成伦敦时间的16:08:05了。
Time转时间戳
直接调用方法func (t Time) Unix() int64即可。将上面的两个时间变量timestamp和timestamp1转为时间戳。
fmt.Println(timestamp.Unix())
fmt.Println(timestamp1.Unix())
// 输出
1542804499
1542804499
时间戳转Time
用函数func Unix(sec int64, nsec int64) Time进行转换,第一个参数是秒,第二个参数是纳秒,会被加到结果的小数点后面。
tmsp := time.Now().Unix()
fmt.Println(tmsp)
t1 := time.Unix(tmsp, 0).UTC()
t2 := time.Unix(tmsp, tmsp).Local()
fmt.Println(t1)
fmt.Println(t2)
// 输出
1542779708
2018-11-21 05:55:08 +0000 UTC
2018-11-21 13:55:09.542779708 +0800 CST
这里的转换可以选择是转换为当地时间还是伦敦时间。