Go语言数据类型大致可以分为两类
基础类型,其中就包括了我们最常见的一些类型
类型名称长度零值说明bool布尔类型1false其值不为真即为家,不可以用数字代表true或falsebyte字节型10uint8别名rune字符类型40专用于存储unicode编码,等价于uint32int, uint整型4或8032位或64位int8, uint8整型10-128 ~ 127, 0 ~ 255int16, uint16整型20-32768 ~ 32767, 0 ~ 65535int32, uint32整型40-21亿 ~ 21 亿, 0 ~ 42 亿int64, uint64整型80float32浮点型40.0小数位精确到7位float64浮点型80.0小数位精确到15位complex64复数类型8complex128复数类型16uintptr整型4或8⾜以存储指针的uint32或uint64整数string字符串“”utf-8字符串复合类型, 这些类型构成了Go语言的特点
指针 (pointer)数字 (array)切片 (slice)字典(map)通道 (chan)结构体 (struct)接口 (interface)整数类型就是存放整数值得
int类型和uint类型自动匹配平台长度
类型有无符号占用空间范围备注int有32位系统4个字节64位系统8个字节 − 2 3 1 2 3 1 − 1 -2^31~2^31-1 −231 231−1 − 2 6 3 2 6 3 − 1 -2^63~2^63-1 −263 263−1uint无32位系统4个字节64位系统8个字节 0 2 3 2 − 1 0~2^32-1 0 232−1 0 2 6 4 − 1 0~2^64-1 0 264−1rune有与int32一样 − 2 3 1 2 3 1 − 1 -2^31~2^31-1 −231 231−1等价int32,表示一个Unicode码byte无与uint8等价0~255存储字符使用Go语言的整型默认声明是int型
通常int和int32被认为是两种不同的类型,编译器不会做自动装换
整数类型可以进行数值运算 (加减乘除和求余)
整数类型可以进行比较运算(> , < ,==, >= , <= ,!=)
两个不同类型的整数不能比较,即使他们的值看着相同也不行
浮点型用于表示包含小数点的数据,例如 1.234 , 0.99 , -9.9等就是一个浮点型数据,Go语言中的浮点型采用 IEEE-754 标准的表达方式
Go语言定义两个浮点类型float32和float64,其中float32相当于C语言中的float类型, float64等价于C语言中的double类型
类型占用存储空间范围单精度float324字节-3.4028234663852886e+38~3.4028234663852886e+38双精度float648字节-1.7976931348623157e+308~1.7976931348623157e+308小数部分可能丢失,造成精度损失,要保存高精度的数应该选择float64
Go语言的浮点型默认是float64类型
package main import "fmt" func main(){ var p1 float32 = 897.0000023 var p2 float64 = 897.0000023 fmt.Println("p1 = ",p1) fmt.Println("p2 = ",p2) p3 := -12.90 // GO语言默认是使用float64类型 fmt.Printf("p3 type = %T",p3) } p1 = 897 p2 = 897.0000023 p3 type = float64需要说明float32 和 float64 是两种类型,不能直接相互赋值
package main import "fmt" var f1 float32 var f2 float64 func main() { f2 = 1212.09 fmt.Printf("f2 type is %T, value is %v\n",f2,f2) // 运行报错 //cannot use f2 (type float64) as type float32 in assignment f1 = f2 fmt.Printf("f1 type is %T, value is %v\n",f1,f1) }我们看看浮点数float32 和 float64类型怎么转换
package main import "fmt" var f1 float32 var f2 float64 func main() { f2 = 1212.09 fmt.Printf("f2 type is %T, value is %v\n",f2,f2) // 强制转换成float32类型 f1 = float32(f2) fmt.Printf("f1 type is %T, value is %v\n",f1,f1) } f2 type is float64, value is 1212.09 f1 type is float32, value is 1212.09Go语言中支持两种字符类型 分别是byte 和 rune
byte型 ,实际上是uint8类型的别称,代表了ASCII码的一个字符
rune 类型,代表一个unicode 字符 ,实际是一个int32类型,在处理中文,日文或者其他符合类型时需要用到,Go语言中使用特殊的rune类型来处理Unicode,让基于Unicode的文本处理更为方便
package main import "fmt" func main() { var a byte = 'a' var b rune = '中' // a的值`a`对应的ASCII编码是97 实际类型是uint8 fmt.Printf("a value = %d type = %T\n", a, a) // b的值`中`对应的Unicode码是20013 实际类型是int32 fmt.Printf("b value = %d type = %T\n", b, b) // 输出对应的字符 fmt.Printf("a = %c b = %c",a,b) } a value = 97 type = uint8 b value = 20013 type = int32 a = a b = 中Unicode 是字符集,ASCII 也是一种字符集,UTF-8是一种编码规则
字符集为每一个字符分配一个唯一的ID,我们使用的所有字符在unicode字符集中都有唯一的ID对应.
utf-8 是编码规则,将unicode字符集中的ID以某种形式进行编码
在Go语言中,字符的本质是一个数字,格式化输出时%c,会输出该数字对应的unicode字符
package main import "fmt" func main(){ var v1 int8 = 102 fmt.Printf("v1 = %c\n",v1) var v2 int = 22381 fmt.Printf("v2 = %c\n",v2) } v1 = f v2 = 坭字符串是可以进行运算的
package main import "fmt" func main() { var v1 int = 10 v1 += 97 fmt.Printf("v1 = %d,unicode = %c",v1,v1) } v1 = 107,unicode = kGo语言字符串数据对应的字节数组,字符串的只读属性禁止了在程序中对底层字节数组的元素修改,字符串赋值只是赋值了数据地址和对应长度,而不会底层数据的赋值
字符串是一串固定长度的字符连接起来的字符序列,Go语言的字符串的字节使用utf-8编码标识的unicode文本
字符串类型也就是string类型定义很简单
package main import "fmt" var s1 string func main() { s1 = "Celtic 凯尔特人" s2 := "Lakers 湖人" var s3 string = "Rocket 火箭" fmt.Printf("s1 = %s type = %T\n",s1,s1) fmt.Printf("s2 = %s type = %T\n",s2,s2) fmt.Printf("s3 = %s type = %T\n",s3,s3) } s1 = Celtic 凯尔特人 type = string s2 = Lakers 湖人 type = string s3 = Rocket 火箭 type = string字符串的内容可以用类似数组下标的方式获取,但是与数组不同的是,字符串的内容不能在初始化之后修改
package main import "fmt" func main() { var s1 string = "hello world ~~" // 使用内置函数len()获取字符串长度 l := len(s1) fmt.Printf("s1 的长度是 : %d\n",l) // 获取第一个字符 ch1 := s1[8] fmt.Printf("%c ch1 = %v,type = %T\n",ch1,ch1,ch1) } s1 的长度是 : 14 r ch1 = 114,type = uint8看一个错误的例子
package main import "fmt" func main() { var s1 string = "hello world ~~" //会报编译错误 s1[0] = "H" fmt.Println(s1[0]) } cannot assign to s1[0]字符串的两种表示形式
双引号 ,字符串的值在书写在双引号中是最常见的表达方式,也称为字符串字面量,这种形式不能跨行,如果字符串太长,可以使用 + 拼接反引号, 以字符串原生样式输出,包括换行和特殊字符 package main import "fmt" func main() { s0 := "hello" + "world" s0 += "\n 中国" fmt.Println(s0) } helloworld 中国 package main import "fmt" func main() { // 定义多行字符串 var s1 string = `怒发冲冠 凭栏处潇潇雨歇 抬望眼 仰天长啸` fmt.Println(s1) } 怒发冲冠 凭栏处潇潇雨歇 抬望眼 仰天长啸以字节数组方式遍历数组
package main import "fmt" func main(){ var s1 string = "golang 中国" // 因为字符占1个字节,汉字占3个字节 所以参数s1的长度是13 l := len(s1) for i:= 0 ;i<l;i++{ ch := s1[i] // 依据下标取字符串中的字符,类型为byte fmt.Printf("%T,%d,%d\n",ch,i,ch) } } uint8,0,103 uint8,1,111 uint8,2,108 uint8,3,97 uint8,4,110 uint8,5,103 uint8,6,32 uint8,7,228 uint8,8,184 uint8,9,173 uint8,10,229 uint8,11,155 uint8,12,189以unicode字符遍历数组
package main import "fmt" func main(){ var s1 string = "golang 中国" for i,v := range s1{ // v是rune类型 fmt.Printf("%d,%T,%d,%c\n",i,v,v,v) } } 0,int32,103,g 1,int32,111,o 2,int32,108,l 3,int32,97,a 4,int32,110,n 5,int32,103,g 6,int32,32, 7,int32,20013,中 10,int32,22269,国Go语言中不同类型变量之间相互赋值时需要显式转换(不能自动转换)
转换的表达式 T(v) , 意思是将v转换成T类型
多见于整数的不同类型之间的转换,或者不同浮点数类型之间的转换,或是整数与浮点数之间的相互转
package main import "fmt" func main() { var v1 int8 = 99 var v2 int fmt.Printf("v1 type is %T,value is %d\n",v1,v1) fmt.Printf("v2 type is %T,value is %d\n",v2,v2) v2 = int(v1) fmt.Printf("v2 type is %T,value is %d\n",v2,v2) } v1 type is int8,value is 99 v2 type is int,value is 0 v2 type is int,value is 99GO语言中数据类型的值范围可以从大向小转换,也可以从小向大转换
package main import "fmt" func main() { // int8 的范围是 -128 ~ 127 var v1 int8 var v2 int64 = 9999999 var v3 float64 // 不会报错, 结果是按溢出处理 v1 = int8(v2) v3 = float64(v2) fmt.Printf("%T, %d\n",v1,v1) fmt.Printf("%T, %f\n",v3,v3) } int8, 127 float64, 9999999.000000在实际应用中,string 类型和基础类型的相互转换非常常见
例如,整数类和浮点数类型,bool型等与string类型之间的转换
基础类型转成string类型
方法1: 通过包 fmt 包的Sprintf()函数去实现
package main import "fmt" func main(){ var v1 int64 = 99998767 var f float64 = 90.7978 var b bool = true var ch byte = 'w' var s string s = fmt.Sprintf("%d",v1) fmt.Printf("v2 = %s, %T\n",s,s) s = fmt.Sprintf("%f",f) fmt.Printf("v2 = %s, %T\n",s,s) s = fmt.Sprintf("%t",b) fmt.Printf("v2 = %s, %T\n",s,s) s = fmt.Sprintf("%c",ch) fmt.Printf("v2 = %s, %T\n",s,s) } v2 = 99998767, string v2 = 90.797800, string v2 = true, string v2 = w, string基础数据类型转换成string类型
方法2 : 使用 strconv 包中的函数实现
package main import ( "fmt" "strconv" ) func main() { var n int8 = 12 var f float64 = 23.001 var b bool = false // FormatInt函数中传入的第一个参数应该是int64类型 s := strconv.FormatInt(int64(n),10) fmt.Printf("s = %s and type = %T\n",s,s) // 其中的参数说明参考文档 s = strconv.FormatFloat(f,'f',10,64) fmt.Printf("s = %s and type = %T\n",s,s) s = strconv.FormatBool(b) fmt.Printf("s = %s and type = %T\n",s,s) } s = 12 and type = string s = 23.0010000000 and type = string s = false and type = stringstrconv 包中有其他的方法可以将string类型转换成整数类型,浮点数类型,bool类型,函数名为 ParseInt() ParseBool() ParseFloat() **ParseUint()
package main import ( "fmt" "strconv" ) func main() { var s1 string = "99090" var s2 string = "12.090" var s3 string = "true" var s4 string = "97" var s5 string = "helloworld" n, _ := strconv.ParseInt(s1, 10, 64) fmt.Printf("n = %d,type = %T\n", n, n) f, _ := strconv.ParseFloat(s2, 64) fmt.Printf("f = %f,type = %T\n", f, f) b, _ := strconv.ParseBool(s3) fmt.Printf("b = %t,type = %T\n", b, b) n2, _ := strconv.ParseUint(s4, 10, 64) fmt.Printf("n2 = %d,type = %T\n", n2, n2) // 错误原因是s5的有效数据不能转换成指定的类型 n3, err := strconv.ParseInt(s5, 10, 64) if err !=nil{ fmt.Println("error = ",err) }else{ fmt.Printf("n = %d,type = %T\n", n3, n3) } } n = 99090,type = int64 f = 12.090000,type = float64 b = true,type = bool n2 = 97,type = uint64 error = strconv.ParseInt: parsing "helloworld": invalid syntax