Go数据类型转化

Go是一种强类型语言,同时也属静态类型语言。

强类型语言

强类型语言也称为强类型定义语言,是一种总是强制类型定义的语言。也就是说一旦一个变量被指定了某个数据类型,如果不经过强制转化,那么它就永远是这个数据类型了。例如下面的代码中,开始处变量str的类型是字符串,接着又赋给变量str一个int类型的值,这是不允许的。

package main

import "fmt"

func main() {
	var str = "hello world"
	str = 123
	fmt.Printf(str)
}

编译执行前,一般开发工具就会给出错误。也可以执行一下,看系统给出的错误提示:

# command-line-arguments
.\test.go:7:6: cannot use 123 (type int) as type string in assignment

静态类型语言

一种在编译时,数据类型是固定的语言,在使用数据之前,必须首先定义数据类型,相当于在使用它们之前,首先要为它们分配好内存环境。静态类型语言的主要优点在于其结构非常规范,便于调试,方便类型安全。缺点是为此需要写更多的类型相关代码,导致不便于阅读,不清晰明了。
简单了解下Go变量的声明,主要有以下几种:

var x int  //只声明,没有设置初始化值。这种情况下会Go会给出默认值,具体介绍可查看[go语言变量声明后的默认值](https://blog.csdn.net/benben_2015/article/details/78777454)
var y = 1.2  //声明的同时提供初始化值,这种情况可省略变量类型,由编译器自动推断
func main() {
    z := "hello world"  //在函数内部,可以用":="方式定义变量
}

类型转化

相同基础类型之间的转化

对于每一个类型T,都有一个对应的类型转化操作T(X)。用于将X转化为T类型(如果T是指针类型,可能会需要用小括弧包裹T,比如(*int)(0))。只有当两个类型的底层基础类型相同时,才允许这种类型操作,或者是两者都是指向相同底层结构的指针类型,这些转化只改变类型而不会影响值本身。如果X可以赋值给T类型的值,那么X必然也可以被转化为T类型。
例如Go语言的数值类型包括:整形数、浮点数和负数,每种数值类型都决定了对应的大小范围和是否支持正负符号。例如下面变量a在开始处的类型为float64,但是通过上面所说的类型转化操作,顺利的将它转化成uint32类型。

package main

import (
	"fmt"
	"reflect"
)

func main() {
	a := 123.4
	fmt.Println("a type is ", reflect.TypeOf(a))  //打印 a type is float64
	b := uint32(a)
	fmt.Println(b)                                //打印 123
	fmt.Println("b type is ", reflect.TypeOf(b))  //打印 b type is uint32
}

那么如果将上面代码中的uint32换成string,编译就会报错,因为它们属于不同的底层基础类型。

# command-line-arguments
.\test.go:11:13: cannot convert a (type float64) to type string

注意: 许多整形数之间的相互转化并不会改变数值,它们只是告诉编译器如何解释这个值。但是对于将一个大尺寸的整数类型转为一个小尺寸的整数类型,或是将一个浮点数转为整数,可能改变数值或丢失精度。比如上面的例子,浮点数到整数的转化将丢失任何小数部分,然后向数轴零方向截断。
同理,相互之间可以转化的类型有:
1.字符类型和字符串类型

package main

import (
	"fmt"
	"reflect"
)

func main() {
	a := 'h'
	fmt.Println(reflect.TypeOf(a))
	b := string(a)
	fmt.Println(reflect.TypeOf(b))
}

上面代码实际上就是byte类型和string类型之间的转化,那么string类型要转化成byte类型也是可以转化的,只不过此时string对应的类型就应该是[]byte类型。例如:

func main() {
	a := "hello world"
	b := []byte(a)
	fmt.Println(b, reflect.TypeOf(b))
}

从执行的情况来看,变量b的类型是[]uint8,也就是[]byte类型。代表UTF-8字符串,[]byte类型还有一种是rune,代表Unicode字符。

不同基础类型之间的转化

对于不同的基础类型之间的转化,Go提供了strconv包。它实现了字符串与其他基本数据类型之间的转化。其中最常用的数值转化函数是AtoiItoa,简单了解下它的使用。Atoi方法可以将字符串类型的数值直接转化为int类型的数值,而Itoa可以将int类型的数值转化为string类型的值。

package main

import (
	"fmt"
	"strconv"
	"reflect"
)

func main() {
	a := "123"
	b, err := strconv.Atoi(a)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(b, reflect.TypeOf(b))
	c := strconv.Itoa(b)
	fmt.Println(c, reflect.TypeOf(c))
}

1.ParseBool函数
此方法用来解析字符串类型的代表的布尔值,此方法中会将"1", "t", "T", "true", "TRUE", "True"全部转化为true,将"0", "f", "F", "false", "FALSE", "False"全部转化为false。而对于其他值,都会返回false,并返回一个错误。

package main

import (
	"fmt"
	"strconv"
	"reflect"
)

func main() {
	a, err := strconv.ParseBool("3")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(a,reflect.TypeOf(a))
}

上面代码编译时就会报错strconv.ParseBool: parsing "3": invalid syntax
2.FormatBool函数
此方法会将bool类型转化为string类型的值,例如:

func main() {
	a := strconv.FormatBool(true)
	fmt.Println(a, reflect.TypeOf(a))
}

3.ParseFloat函数
此方法将string类型转化成float64的值,其中第二个参数用来控制返回时数值的精度,32标识float32,64表示float64。
当精度是32时,结果返回的类型仍然是float64,但是它可以在不改变其值的情况下转化为float32。
4.FormatFloat函数
此方法将float64类型的变量转化为string类型,总共需要传入四个参数。第一个是转化的数值,第二个是控制打印时的格式,第三个是特殊的精度,最后一个也是特殊的精度。

func FormatFloat(f float64, fmt byte, prec, bitSize int) string {}

该包中还有一些其他的类型转化函数,如果感兴趣,可以下去再仔细了解一下。

你可能感兴趣的:(GO学习总结)