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
包。它实现了字符串与其他基本数据类型之间的转化。其中最常用的数值转化函数是Atoi
和Itoa
,简单了解下它的使用。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 {}
该包中还有一些其他的类型转化函数,如果感兴趣,可以下去再仔细了解一下。